
编程语言:C
文章平均质量分 85
工作中用到C语言
在此记录遇到的问题,可以精进的方面
z_stand
远离颠倒梦想,究竟涅槃
展开
-
使用 sched_setaffinity 将线程绑到CPU核上运行
linux 提供CPU调度函数,可以将CPU某一个核和指定的线程绑定到一块运行。这样能够充分利用CPU,且减少了不同CPU核之间的切换,尤其是在IO密集型压力之下能够提供较为友好的性能。通过sched_setaffinity 设置 CPU 亲和力的掩码,从而将该线程或者进程和指定的CPU绑定一个CPU的亲合力掩码用一个cpu_set_t结构体来表示一个CPU集合,下面的几个宏分别对这个掩码集进行操作:CPU_ZERO() 清空一个集合CPU_SET()与CPU_CLR()分别对将一个给定的CPU号原创 2020-08-08 18:30:21 · 9556 阅读 · 0 评论 -
C++ STL: 分配器allocators 源码分析
STL 基本的六大组件作用以及功能如下:可以看到allocator是数据存储组件container的幕后支持者,负责为其数据存储分配对应的存储空间。operator::new在详细介绍alloctor之前,先描述一下new运算符,我们使用C++ new一个对象的时候就是调用底层operator::new运算符,实现如下:void * operator new(std::size_t size){ ++allocations; void * retval = malloc(size原创 2020-06-15 09:21:23 · 726 阅读 · 0 评论 -
C++ STL: 基本六大部件概览 及 各个容器使用方式和底层实现概览
文章目录STL六大部件容器的使用Arrayvectorlistdequemutisetmultimapunordered_multiset/set使用一个东西,却不明白它的道理,不高明。STL六大部件容器 Containers 用来存放数据分配器 Allocators 为容器内大数据分配存储空间算法 Algorithms 计算数据迭代器 Iterators 访问数据大方式(算法使用其访问容器内大数据)适配器 Adapters仿函数 Functors 类似于函数的功能六大组件之间原创 2020-06-12 00:58:41 · 833 阅读 · 0 评论 -
C++ 中emplace_back和push_back差异
前言最近看rocskdb源码,发现了大量的设计模式和C++高级特性,特此补充一下,巩固基础。问题描述其中关于动态数组的元素添加,代码中基本将push_back抛弃掉了,全部替换为emplace_back进行元素的添加。看了一下官网描述:原来的push_back 一个右值元素的时候 过程分为如下几步:使用右值数据类型的构造函数 构造一个临时对象调用拷贝构造函数将临时对象放入 容器中释放临时对象可以看到以上的三个步骤,临时对象的资源就没有用到,而且还多了一次拷贝构造的过程,效率大大降低后原创 2020-06-02 22:33:14 · 1104 阅读 · 0 评论 -
C++ 泛型编程 -- 函数模版
文章目录定义声明调用方式函数模版的重载函数模版的特点工作中一个同事写了测试demo,想要自己尝试使用发现调用老出错,请教的时候发现是函数模版,有自己的调用方式,并且发现核心代码中大量的函数模版和类模版。特此做一个函数模版相关的总结,为今后更加熟练的开发做好铺垫。定义C++中,存在泛型编程的概念:即不考虑具体数据类型的编程方式函数模板是一种特殊的函数,可以使用不同的类型进行调用,对于功能相同的函数,不需要重复编写代码,并且函数模板与普通函数看起来很类似,区别就是类型可以被参数化声明函数模版的声原创 2020-05-14 01:46:38 · 365 阅读 · 0 评论 -
设计模式 之美 -- 原型模式
文章目录1. 解决问题2. 应用场景3. 实现方式C++实现C语言实现4. 缺点5. 和其他三种创建模式的对比(单例,工厂,建造者)1. 解决问题如果对象的创建成本较大,而同一个类的不同对象之间的差别不大(大部分字段相同),在这种情况下,我们可以利用已有对象(原型)进行赋值(拷贝)的方式,创建新的对象,从而达到节省对象创建时间的目的。2. 应用场景需要在运行过程中,动态的拷贝一份对象需...原创 2020-04-24 21:18:09 · 272 阅读 · 0 评论 -
设计模式 之美 -- 工厂方法模式
文章目录1. 解决问题2. 应用场景3. 实现如下C++实现C语言实现4. 缺点1. 解决问题在简单工厂模式中,我们使用卖衣服进行举例,同一种工厂可以卖很多不同种类的衣服,工厂只是将衣服的生产过程进行了封装。当我们增加衣服种类的时候,在简单工厂模式中需要对修改工厂的代码,破坏了类的开闭原则(对扩展开发, 对修改关闭),同时增加测试成本。此时为了避免这种问题的出现,我们推出工厂方法模式,为每...原创 2020-04-20 23:01:30 · 308 阅读 · 0 评论 -
C语言 #ifndef 引起的redefinition of xxx 问题解决
问题如下多个.c和.h文件其中cloth.h分布被hat.h和paths.h包含,编译时出现如下问题:error: redefinition of struct _Cloth我的cloth.h定义如下:#include <stdio.h>#include <stdlib.h>#include "retval.h"struct _Cloth;typede...原创 2020-04-16 23:11:57 · 5196 阅读 · 0 评论 -
设计模式 之美 -- 简单工厂模式
文章目录1. 解决问题2. 应用场景3. 实现C++实现:C语言实现4. 缺点1. 解决问题举例如下:我们实现一个卖衣服的功能,衣服的种类有很多:帽子,裤子,T恤。。。 每卖一种衣服,我们都要进行一次实例化,通过new/malloc申请空间,会有如下两种问题:new /malloc之后往往需要跟随一堆异常处理代码,当衣服种类越来越多,我们的代码会显得异常臃肿。当新的服务员来到商店,他想...原创 2020-04-16 23:10:32 · 319 阅读 · 0 评论 -
设计模式 之美 -- 单例模式
为什么要使用单例?一个类只允许创建一个对象或者实例。背景简介:使用多线程并发访问同一个类,为了保证类的线程安全,可以有两种方法:将该类定义为单例模式,即该类仅允许创建一个实例为该类的成员函数添加类级别的锁举例:一个向指定文件写入日志的类,为了保证该类并发调用时写入文件的日志不会覆盖,需执行以上操作。单例模式的几种经典的实现方式:饿汉式在类的加载期间,将静态实例初始化好...原创 2020-04-13 22:42:36 · 356 阅读 · 0 评论 -
设计模式 之美 -- 面向对象(C/C++分别实现)
前言为了保证代码的可复用性、可扩展性、可维护性,我们提出了面向对象的思想。面向对象的核心特性有以下几个封装特性信息隐藏或者数据访问保护。类通过暴露有限的访问接口,授权外部仅能通过类提供的方式来访问内部信息或者数据。封装用来提升代码的可扩展性、可维护性继承特性继承是用来表示类之间的 is-a 关系,分为两种模式:单继承和多继承。单继承表示一个子类只继承一个父类,多继承表示一个子类可以...原创 2020-04-11 09:33:23 · 388 阅读 · 0 评论 -
多线程:pthread_cond_wait 实现原理
函数原型int pthread_cond_wait(pthread_cond_t *cond, pthread_mutex_t *mutex)第一个参数为需要等待的条件,第二个参数为互斥锁一般该函数和 int pthread_cond_signal(pthread_cond_t *cond);函数一同使用,用来唤醒在cond条件上等待且处于就绪队列的线程执行。代码举例#include&l...原创 2020-02-14 11:47:29 · 3190 阅读 · 4 评论 -
linux open系统调用的O_DIRECT标记
前言open系统调用中针对打开的文件描述符,可以增加一个O_DIRECT标记,该标记能够使得针对该文件描述符的写操作绕过操作系统page cache,直接进入通用块设备层,从而减少页缓存对IO效率的影响。但是针对O_DIRECT标记有一个问题,数据及其元数据尝试落盘但是无法保证完整落盘,如果保证落盘,则需要O_SYNC的标记支持,即IO到达块设备才会返回,来确保用户态的数据安全性。代码测试...原创 2019-12-02 21:34:47 · 1756 阅读 · 0 评论 -
C语言的单链表实现队列
队列是一种FIFO(先入先出)的数据结构C++的STL std::queue q; 相关的队列操作,包括q.empty() 判读队列是否为空q.front() 返回队列的首元素q.back() 返回队列的末尾元素q.pop() 弹出队列的头部q.push(x) 将x添加至队列q.size() 返回队列的大小本文使用C语言的链表,实现队列以上操作(文末有测试代码)emptybo...原创 2019-10-29 23:56:41 · 376 阅读 · 0 评论 -
C语言的双向链表头插法和尾插法,指定节点删除
文章目录前言头插法尾插法删除节点测试代码如下前言双向链表和单链表的唯一区别就是多个一个指针域而已,该指针域可以访问链表的上一个节点。关于构造双向链表的过程我们常见的有两种方法,和单链表一样:头插法和尾插法。头插法:字面意思也是很好理解,每次插入的元素在上一个节点之前尾插法:字面意思也表达出了每次的元素插入会在上一个节点之后详细插入过程可以参考如下头插法头插法基本过程如下图,已经描...原创 2019-10-29 00:58:30 · 3359 阅读 · 1 评论 -
C语言的有序单链表合并
已知两个已排序链表头节点指针headA与headB,将这两个链表合并,合并后仍为 有序的,返回合并后的头节点。主要步骤如下:创建一个临时的头节点,头节点每次指向headA 或者 headB较小的节点当headA->data 比headB->data小的时候,headA的当前节点加入临时头节点,同时headA指针向后移动;否则headB加入临时头节点,同时headB指针向后移动...原创 2019-10-24 00:34:45 · 1682 阅读 · 0 评论 -
C语言的单链表分割
已知链表头指针head与数值x,将所有小于x的节点放在大于或等于x 的节点前,且保持这些节点的原来的相对位置。这个过程有点类似于快速排序,寻找一个阈值,比该阈值小的放左边,比该阈值大的放右边。只是由数组遍历变为来链表遍历,操作变成了指针的指向。具体步骤如下:创建一个less_ptr,负责对less端的链表进行维护创建一个more_ptr,负责对more端的链表进行维护最终进行less...原创 2019-10-21 23:25:27 · 969 阅读 · 0 评论 -
C语言单链表求环,并返回环的起始节点
若链表中存在环,找出其中的环所在的节点,否则,返回NULL在没有C++ set容器的优势前提下,我们对这样的环型的寻找以及定位可以利用快慢指针来实现。有环的存在,类似与操场跑圈,必然存在快慢之分。有了快慢,就一定会有交点。反之,有了交点,就一定存在环。实现过程如下:slow指针移动一次,fast指针移动两次,当fast指针和slow指针相等时保留相等时的节点根据运算,从相等时的节点和...原创 2019-10-21 23:05:25 · 504 阅读 · 0 评论 -
C语言的单链表求交点
单链表求交点,问题如下:使用o(1)的空间复杂度,求两个链表相交的时候的交点,这个思想就类似于使用o(1)的空间复杂度和o(n)的时间复杂度来求链表的第k个节点。过程如下:获取两个链表的长度将较长的链表移动和短链表长度差值的位置移动后两个链表长度一样,然后一起移动,这样就知道节点相等的时候链表相交算法实现如下:get_intersection_node函数/*获取交叉链表的节...原创 2019-10-21 22:49:15 · 668 阅读 · 0 评论 -
C语言的单链表逆序和指定范围逆序
前言关于链表的逆置,是考察对链表指针的理解。知道了如何不实用额外空间,同时使用O(n)复杂度对链表进行逆序之后将会对链表有好理解。同时关于如何在指定范围内对链表逆置同样可以进一步加深理解逆序基本过程如下:保留原始链表的next指针域,p = head -> next将原始链表的next指针域指向新链表的头部,head -> next = new_head新链表指针向前移...原创 2019-10-21 00:10:34 · 378 阅读 · 0 评论 -
C语言的单链表创建:头插法/尾插法
文章目录前言链表头插法链表尾插法源码实现前言接下来一段时间,将对数据结构进行复习,总的来说数据结构自大学之后忘记得有点吓人,为了防止脑容量本就小得脑袋更小,必须得持续性得温故了。链表数据结构得提出 是为了弥补数组上 元素插入、删除导致大量元素移动得缺点,这里将C语言得指针提取出来构造一个指针管理得存储数据得结构,使用链式得方式消耗极少对资源(指针的指向,地址得删除)能够对单个元素得插入删除进...原创 2019-10-21 00:11:05 · 547 阅读 · 0 评论 -
C语言网络编程:多路IO select实现多客户端
文章目录阻塞式的服务器程序多线程服务器程序非阻塞式服务器程序基于事件响应的服务器程序事件响应服务器程序的实现`select`阻塞式的服务器程序我们接触过最多的最基础的网络通信模型为TCP/UDP通信模型,以下为TCP通信模型的基本流程C语言网络编程:TCP客户端实现但是以上过程中每个通信函数都是阻塞的,而且建立连接之后的数据接收发送同样是阻塞形式的。send无法发送时只能继续阻塞,recv...原创 2019-10-19 14:11:18 · 2040 阅读 · 1 评论 -
C语言网络编程:TCP实现多线程实现多客户端
TCP通信的编程模型如下:TCP通信是必须要有一个服务器,通过accept函数与客户端socket进行三次握手连接创建的通信描述符与客户端进行数据传输。此时可以将accept函数的连接设置为多线程形式,轮训监听,每获取到一个客户端的连接,则创建一个子线程专门用于和该客户端进行通信。实现代码如下:server.c#include <stdio.h>#include <...原创 2019-10-17 00:00:25 · 10213 阅读 · 0 评论 -
C语言网络编程:UDP通信实现
UDP描述UDP的特点:udp 协议是一种无链接的不可靠传输协议,且UDP每次发送到分组数据大小都是固定的,它的主要特点如下:不建立连接没有应答机制不会根据网络状况的好坏调整分组数据的大小...原创 2019-10-16 01:05:50 · 4311 阅读 · 0 评论 -
C语言网络编程:TCP客户端实现
文章目录客户端通信步骤为什么客户端没有bind和listen客户端connect函数介绍局域网内客户端和服务器通信代码实例客户端通信步骤根据基本TCP网络通信编程模型我们可以知道客户端的实现主要有几个步骤socket创建客户端通信的套接字文件,并指定通信的协议族和数据类型使用connect主动向服务器发起连接请求,与服务器的accept实现三次握手建立连接。连接成功之后客户端可以通过...原创 2019-10-15 13:02:57 · 3862 阅读 · 0 评论 -
C语言网络编程:close或者shutdown断开通信连接
这里在主要通过实例进行描述close函数在网络编程中的使用TCP编程模型中客户端或者服务器只要主动通过close发起断开连接的请求,则通信连接可以中断。可以通过在主进程中抓取通信端的断开信号,比如SIGINT,在信号处理函数中对该通信文件描述符进行关闭。如下代码#include <stdio.h>#include <stdlib.h>#include <u...原创 2019-10-15 00:30:28 · 2495 阅读 · 0 评论 -
C语言网络编程:recv函数详解
函数描述头文件 #include <sys/socket.h>ssize_t recv(int sockfd, void *buf, size_t len, int flags);函数功能:接收对方发送当数据可以同样使用recvfrom函数来接收数据ssize_t recvfrom(int sockfd, void *buf, size_t len, int flags,s...原创 2019-10-15 00:30:56 · 23362 阅读 · 2 评论 -
C语言网络编程:send函数详解
函数描述#include <sys/socket.h>ssize_t send(int sockfd, const void *buf, size_t len, int flags);函数功能:向对方发送数据其实也可以使用sendto函数:ssize_t sendto(int sockfd, const void *buf, size_t len, int flags, c...原创 2019-10-15 00:31:05 · 20377 阅读 · 0 评论 -
C语言网络编程:accept函数详解
文章目录前言函数描述代码实例如何得到客户端的IP 和 端口号前言当使用tcp服务器使用socket创建通信文件描述符,bind绑定了文件描述符,服务器ip和端口号,listen将服务器端的主动描述符转为被动描述符进行监听之后,接口accept通过三次握手与客户端建立连接TCP 编程模型如下:函数描述#include <sys/socket.h>int accept(i...原创 2019-10-15 00:31:26 · 15177 阅读 · 6 评论 -
C语言网络编程:listen函数详解
文章目录前言函数描述代码实例TCP服务器为什么调用listen前言根据TCP编程模型中我们可以看到之前的socket和bind接口是tcp服务器在为接收客户端的链接做准备,保证tcp的面向字节流,面向连接的可靠通信服务正常进行。接下来的listen端口则为我们进行三次握手与客户端进行链接的接口。TCP编程模型如下函数描述#include <sys/socket.h>i...原创 2019-10-15 00:31:35 · 10248 阅读 · 1 评论 -
C语言网络编程:bind函数详解
文章目录函数功能函数头文件函数使用函数参数函数举例为什么需要bind函数服务器如何知道客户端的ip和端口号htons函数`htons`兄弟函数`htonl`,`ntohs`,`ntohl`为什么要进行端口的大小端序的转换`inet_addr`函数函数功能bind API能够将套接字文件描述符、端口号和ip绑定到一起注意:绑定的一定是自己的 ip和和端口,不是对方的;比如对于TCP服务器来说...原创 2019-10-15 00:31:43 · 16830 阅读 · 2 评论 -
C语言网络编程:socket函数
函数描述头文件 <sys/types.h> <sys/socket.h>函数使用int socket(int domain, int type, int protocol);函数功能:创建一个通信的终点,并返回一个文件描述符来代表通信的终点函数参数:a. domain 代编当前创建的socket文件描述符使用的是哪一个协议族进行通信,这些协议族都包...原创 2019-10-15 00:31:54 · 2732 阅读 · 0 评论 -
C语言网络编程:TCP编程模型
编程模型TCP编程模型如下TCP服务器的工作过程如下:服务器创建一个专门的“文件描述符”来监听来自客户端的“三次握手”,然后建立链接链接建立成功后,服务器会分配一个专门的“通信文件描述符”,用于实现与该客户端的通信以上通信模型是由于TCP本身的特点:面向连接的,可靠的,字节流通信方式通信过程服务器:创建套接字,返回套接字的文件描述符skfd = socket()将套接字文...原创 2019-10-15 00:32:03 · 909 阅读 · 0 评论 -
linux进程间通信:消息队列实现双端通信
双端通信描述利用消息队列针对发送接受消息的类型唯一性 进行多个客户端之间消息传递,而不需要server端进行消息转发。同时消息队列的读阻塞和写阻塞特性(消息队列中已经写入数据,如果再不读出来,则无法再次写入)让消息队列的实现过程只能如下:客户端1的父进程用来处理类型1的消息写,子进程处理类型2的消息读客户端2的父进程处理类型2的消息写,子进程处理类型1的消息读实现客户端1 clie...原创 2019-09-27 08:55:09 · 562 阅读 · 0 评论 -
linux进程间通信:system V消息队列
基本介绍支持不同进程之间以消息(messages)的形式进行数据交换,消息能够拥有自己的标识,且内核使用链表方式进行消息管理。进程之间的通信角色为:发送者和接受者发送者:a. 获取消息队列的ID(key或者msgid)b. 将数据放入一个带有标识的消息结构体,发送到消息队列接受者:a. 获取消息队列的IDb. 指定标识的消息从消息队列中读出,然后进一步后续处理支持不同的进程标记...原创 2019-09-26 13:14:37 · 365 阅读 · 0 评论 -
linux进程间通信:FIFO实现进程间的双向通信
fifo的双向通信的方式如下图:两个进程间的通信需要两个命名管道,分别处理一个进程的读和写导致这种通信方式出现的根因还是由于fifo的阻塞读和阻塞写,所以这里需要使用两个管道对读写进行分别处理。SERVER端代码如下:/************************************************************************* > File ...原创 2019-09-25 11:44:28 · 1974 阅读 · 0 评论 -
linux进程间通信:FIFO应用 /var/log/ 系统日志的模拟实现
在类unix操作系统下存在这样一个目录/var/log/,主要是记录操作系统相关的系统各个进程服务的日志信息该日志系统的特性如下:支持多进程并发写入同一文件不同进程日志信息可以写入不同文件支持使用head/tail/grep/cat/vi 等命令进行日志操作我们可以利用mkfifo的原子特性来实现一个类似的日志系统,基本结构如下写入fifo的进程代码如下:/*********...原创 2019-09-24 16:43:31 · 598 阅读 · 0 评论 -
linux进程间通信:命名管道FIFO
文章目录FIFO 通信特点系统调用接口应用拥有亲缘关系之间的进程通信非亲缘关系进程之间的通信总结FIFO 通信特点FIFO文件有文件名可以像普通文件一样存储在文件系统之中可以像普通文件一样使用open/write读写和pipe文件一样属于流式文件,不能使用lseek系统调用重定位文件偏移地址具有写入原子性,支持多个进程同时对FIFO进行写操作,如日志系统/var/logFir...原创 2019-09-20 18:06:23 · 461 阅读 · 0 评论 -
linux 系统调用 read,write和lseek 使用
read系统调用头文件 #include <unistd.h>函数使用 ssize_t read(int fd, void *buf, size_t count)read 函数会从文件描述符fd中读取指定的count长度的内容,并且将读到的结果放入到buf缓冲区中返回值count 读取成功,则会返回读到的字节数小于count 表示同样读取成功,只是fd从current o...原创 2019-09-18 13:10:22 · 2543 阅读 · 1 评论 -
linux进程通信:pipe实现进程同步
文章目录通过管道同步进程实现代码管道缓冲区设置缓冲区大小总结 :pipe的特点通过管道同步进程管道自带同步互斥机制:管道的内核实现:fs/pipe.c ,主要通过内核的锁以及等待队列等机制实现管道的write操作会阻塞进程当内存缓冲区已满或被读进程锁定,会阻塞write操作当所有数据被写入管道时write操作才会结束管道的read操作会阻塞进程当读进程被阻塞时会形成...原创 2019-09-13 18:32:42 · 1480 阅读 · 0 评论