IO多路复用
select
与多进程和多线程技术相比,I/O多路复用技术的最大优势是系统开销小,系统不必创建进程/线程,也不必维护这些进程/线程,从而大大减小了系统的开销。
nfds:委托内核检测的这三个集合中最大的文件描述符 + 1,内核需要线性遍历这些集合中的文件描述符,这个值是循环结束的条件 在Window中这个参数是无效的,指定为-1即可 readfds:文件描述符的集合, 内核只检测这个集合中文件描述符对应的读缓冲区,传入传出参数 writefds:文件描述符的集合, 内核只检测这个集合中文件描述符对应的写缓冲区,传入传出参数 exceptfds:文件描述符的集合, 内核检测集合中文件描述符是否有异常状态,传入传出参数 timeout:超时时长,用来强制解除select()函数的阻塞的 NULL:函数检测不到就绪的文件描述符会一直阻塞。 等待固定时长(秒):函数检测不到就绪的文件描述符,在指定时长之后强制解除阻塞,函数返回0 不等待:函数不会阻塞,直接将该参数对应的结构体初始化为0即可。 函数返回值: 大于0:成功,返回集合中已就绪的文件描述符的总个数 等于-1:函数调用失败 等于0:超时,没有检测到就绪的文件描述符
文件描述符表默认1024bit,select中途会产生集合的复制
// 将文件描述符fd从set集合中删除 == 将fd对应的标志位设置为0 void FD_CLR(int fd, fd_set *set); // 判断文件描述符fd是否在set集合中 == 读一下fd对应的标志位到底是0还是1 int FD_ISSET(int fd, fd_set *set); // 将文件描述符fd添加到set集合中 == 将fd对应的标志位设置为1 void FD_SET(int fd, fd_set *set); // 将set集合中, 所有文件文件描述符对应的标志位设置为0, 集合中没有添加任何文件描述符 void FD_ZERO(fd_set *set);
epoll
int epoll_create(int size);
-
函数参数 size:在Linux内核2.6.8版本以后,这个参数是被忽略的,只需要指定一个大于0的数值就可以了。
// 联合体, 多个变量共用同一块内存 typedef union epoll_data { void *ptr; int fd; // 通常情况下使用这个成员, 和epoll_ctl的第三个参数相同即可 uint32_t u32; uint64_t u64; } epoll_data_t; struct epoll_event { uint32_t events; /* Epoll events */ epoll_data_t data; /* User data variable */ }; int epoll_ctl(int epfd, int op, int fd, struct epoll_event *event);
-
op:控制通过该函数执行什么操作
-
EPOLL_CTL_ADD
:往epoll模型中添加新的节点 -
EPOLL_CTL_MOD
:修改epoll模型中已经存在的节点 -
EPOLL_CTL_DEL
:删除epoll模型中的指定的节点
-
-
fd:文件描述符,即要添加/修改/删除的文件描述符
-
events:委托epoll检测的事件
-
EPOLLIN
:读事件, 接收数据, 检测读缓冲区,如果有数据该文件描述符就绪 -
EPOLLOUT
:写事件, 发送数据, 检测写缓冲区,如果可写该文件描述符就绪 -
EPOLLERR
:异常事件
-
-
data:用户数据变量,这是一个联合体类型,通常情况下使用里边的
fd
成员,用于存储待检测的文件描述符的值,在调用epoll_wait()
函数的时候这个值会被传出。 -
int epoll_wait(int epfd, struct epoll_event * events, int maxevents, int timeout);
-
函数参数:
-
epfd:epoll_create() 函数的返回值, 通过这个参数找到epoll实例
-
events:传出参数, 这是一个结构体数组的地址, 里边存储了已就绪的文件描述符的信息
-
maxevents:修饰第二个参数, 结构体数组的容量(元素个数)
-
timeout:如果检测的epoll实例中没有已就绪的文件描述符,该函数阻塞的时长, 单位ms 毫秒
-
0:函数不阻塞,不管epoll实例中有没有就绪的文件描述符,函数被调用后都直接返回
-
大于0:如果epoll实例中没有已就绪的文件描述符,函数阻塞对应的毫秒数再返回
-
-1:函数一直阻塞,直到epoll实例中有已就绪的文件描述符之后才解除阻塞
-
-
-
函数返回值:
-
成功:
-
等于0:函数是阻塞被强制解除了, 没有检测到满足条件的文件描述符
-
大于0:检测到的已就绪的文件描述符的总个数
-
-
-
-
CMake
cmake_minimum_required(VERSION 3.0) 最低版本 project(CALC) 工程名称 add_executable(app add.c div.c main.c mult.c sub.c) 生成可执行程序
CMAKE_CXX_STANDAD 指定c++版本
EXECUTABLE_OUTPUT_PATH 输出路径
CMAKE_CURRENT_SOURCE_DIR 宏表示当前访问的 CMakeLists.txt 文件所在的路径。
LIBRARY_OUTPUT_PATH 指定静态/动态库生成路径
set(SRC_LIST add.c;div.c;main.c;mult.c;sub.c) 变量赋值字符串,
aux_source_directory(< dir > < variable >) 查找某个路径下全部源文件
file(GLOB/GLOB_RECURSE 变量名 要搜索的文件路径和文件类型) GLOB_RECURSE:递归搜索指定目录
include_directories(headpath) 指定头文件路径
add_library(库名称 STATIC 源文件1 [源文件2] ...) shared 动态库
link_directories(<lib path>)静态库连接
target_link_libraries(
<target>
<PRIVATE|PUBLIC|INTERFACE> <item>...
[<PRIVATE|PUBLIC|INTERFACE> <item>...]...) 连接动态库,public有传递性,在程序生成之后
list(APPEND <list> [<element> ...]) 变量追加
list(REMOVE_ITEM <list> <value> [<value> ...])变量移除
link_directories(<lib path>) 指定库的路径