select多路复用的使用
特点:作为中介->Select负责管理这两个阻塞的状态->它啥事业不干,专门看这两个阻塞的函数有没有接收数据。
目的:就是让这些有阻塞的函数不会有阻塞(遍历操作)
缺点:其运行机制实质是在里面进行文件的遍历的过程,当遍历的文件多路,耗费的时间变长,效率变低,实时性跟不上
原理图:
创建流程:
1、创建套接字
2、绑定
3、监听
函数
int select(int nfds, fd_set *readfds, fd_set *writefds, fd_set *exceptfds, struct timeval *timeout);
中文解释
int select(最大文件描述符+1, 读文件描述集合, 写文件描述符集合, 异常文件描述符集合, 设置等待时间,NULL表示一直等待直到有响应)
操作文件描述符集合的函数
void FD_CLR(int fd, fd_set *set); 从set集合中把fd清除
int FD_ISSET(int fd, fd_set *set); 判断set中fd是否响应
void FD_SET(int fd, fd_set *set); 把fd添加到set集合中
void FD_ZERO(fd_set *set); 把集合set清空
书写例子
//用select类监听sockfd
int maxfd = sockfd;//保存最大文件描述符
fd_set readfds;//保存读文件描述符集合
int ret = select(maxfd+1, &readfds, NULL, NULL, NULL);
用select多路复用监听accept和write函数解除阻塞的事例代码:
#include <stdio.h>
#include <sys/socket.h>
#include <sys/types.h>
#include <string.h>
#include <netinet/in.h>
#include <unistd.h>
#include <pthread.h>
#include <semaphore.h>
#include "cJSON.h"
#include <stdbool.h>
#include <arpa/inet.h>
#define MAXSIZE 100
void *client_thread(void *arg);
sem_t sm;
struct ClientInfo{
int sockfd;
char id[16];
};
//定义一个结构体数组
struct ClientInfo cinfo[MAXSIZE];
int main(void)
{
//1.创建套接字
int sockfd = socket