做网站最主要是那个一类商标,推广管理,做翻译 网站吗,单位做核酸简讯TCP并发模型
1.TCP多线程模型#xff1a;
缺点#xff1a;
1#xff09;创建线程会带来资源开销#xff0c;能够实现
2.IO模型#xff1a;
1#xff09;阻塞IO#xff1a;没有数据到来时#xff0c;可以让任务故挂起#xff0c;节省CPU资源开销#xff0c;提高系…TCP并发模型
1.TCP多线程模型
缺点
1创建线程会带来资源开销能够实现
2.IO模型
1阻塞IO没有数据到来时可以让任务故挂起节省CPU资源开销提高系统效率
2非阻塞IO程序未接受到数据时程序一直执行效率很低
3异步IO只能绑定一个文件描述符用来读取数据但是效率很高
4多路复用IO
select 1.select监听的集合中的文件描述符有上限限制 fd_set 2.select有内核层向用户层数据空间拷贝的过程占用系统资源开销 3.select必须轮询检测产生事件的文件描述符 4.select只能工作在水平触发模式低速模式无法工作在边缘触发高速模式
poll 1.poll监听集合中的文件描述符没有上限 2.poll有内核层向用户层数据空间拷贝的过程,占用系统资源开销 3.poll必须轮询检测产生事件的文件描述符 4.poll只能工作在水平触发模式(低速模式),无法工作在边沿触发(高速模式)
epoll
3.函数接口
1select int select(int nfds, fd_set *readfds, fd_set *writefds, fd_set *exceptfds, struct timeval *timeout);
功能select建听描述符集合中是否有文件描述编程ready状态
参数nfds最大文件买哦舒服的值1 readfds读文件描述符集合 writefds写文件描述符集合 exceptfds:其余文件描述符集合 timeout:等待的时长 NULL 一直等待
返回值成功返回文件描述符集合中的文件描述个数失败返回-1
void FD_CLR(int fd, fd_set *set);
功能将文件描述符fd从集合中清除
int FD_ISSET(int fd, fd_set *set);
功能判断文件描述符fd是否仍在集合中
void FD_SET(int fd, fd_set *set);
功能将文件描述符fd加入到集合中
void FD_ZERO(fd_set *set);
功能将文件描述符集合清0
写端
#include head.hint main(void)
{int fd 0;char tmpbuff[4096] {0};mkfifo(/tmp/myfifo, 0777);fd open(/tmp/myfifo, O_WRONLY);if (-1 fd){perror(fail to open);return -1;}while (1){gets(tmpbuff);write(fd, tmpbuff, strlen(tmpbuff));}close(fd);return 0;
}
读端
#include head.hint main(void)
{int fd 0;int flags 0;char *pret NULL;ssize_t nsize 0;char tmpbuff[4096] {0};fd_set rdfds;fd_set tmpfds;int ret 0;mkfifo(/tmp/myfifo, 0664);fd open(/tmp/myfifo, O_RDONLY);if (-1 fd){perror(fail to open);return -1;}FD_ZERO(rdfds);//将文件描述符集合清0FD_SET(fd, rdfds);//将文件描述符fd加入到文件描述符集合中FD_SET(0, rdfds);//将文件描述符0加入到文件描述符集合中while (1){tmpfds rdfds;ret select(fd1, tmpfds, NULL, NULL, NULL);if (-1 ret){perror(fail to select);return -1;}if (FD_ISSET(fd, tmpfds))//判断文件描述符fd是否还在文件描述符集合中{memset(tmpbuff, 0, sizeof(tmpbuff));read(fd, tmpbuff, sizeof(tmpbuff));printf(FIFO:%s\n, tmpbuff);}if (FD_ISSET(0, tmpfds)){memset(tmpbuff, 0, sizeof(tmpbuff));gets(tmpbuff);printf(STDIN:%s\n, tmpbuff);}}close(fd);return 0;
}
2poll
int poll(struct pollfd *fds, nfds_t nfds, int timeout);
功能监听文件描述符集合是否有事件发生
参数
fds监听文件描述符集合数组空间的首地址
nfds监听文件描述符集合元素个数
timeout等待的时间-1 一直等待
返回值成功返回失败返回产生文件描述符的个数失败返回-1
struct pollfd { int fd; /* file descriptor */ short events; /* requested events */ short revents; /* returned events */ }; fd:监听的文件描述符 events:要监听的事件 POLLIN:是否可读 POLLOUT:是否可写 revents:实际产生的事件
读端
#include head.hint main(void)
{int fd 0;int flags 0;char *pret NULL;ssize_t nsize 0;char tmpbuff[4096] {0};struct pollfd fds[2];int nready 0;mkfifo(/tmp/myfifo, 0664);fd open(/tmp/myfifo, O_RDONLY);if (-1 fd){perror(fail to open);return -1;}fds[0].fd fd;fds[0].events POLLIN;fds[1].fd 0;fds[1].events POLLIN;while (1){nready poll(fds, 2, -1);if (-1 nready){perror(fail to poll);return -1;}if (fds[0].revents POLLIN){memset(tmpbuff, 0, sizeof(tmpbuff));read(fd, tmpbuff, sizeof(tmpbuff));printf(FIFO:%s\n, tmpbuff);}if (fds[1].revents POLLIN){memset(tmpbuff, 0, sizeof(tmpbuff));gets(tmpbuff);printf(STDIN:%s\n, tmpbuff);}}close(fd);
}
写端
#include head.hint main(void)
{int fd 0;char tmpbuff[4096] {0};mkfifo(/tmp/myfifo, 0664);fd open(/tmp/myfifo, O_WRONLY);if (-1 fd){perror(fail to open);return -1;}while (1){gets(tmpbuff);write(fd, tmpbuff, strlen(tmpbuff));}close(fd);return 0;
}
3epoll
int epoll_create(int size);
功能创建一张内核事件表
参数size事件个数
返回值成功返回文件描述符失败返回-1 epoll_ctl
int epoll_ctl(int epfd, int op, int fd, struct epoll_event *event);
功能维护epoll事件表
参数
epfd事件表的个数
op EPOLL_CTL_ADD 添加事件 EPOLL_CTL_MOD 修改事件 EPOLL_CTL_DEL 删除事件
fd操作的文件描述符
event事件对应的事件
typedef union epoll_data { void *ptr; int fd; uint32_t u32; uint64_t u64; } epoll_data_t;
struct epoll_event { uint32_t events; /* Epoll events */ epoll_data_t data; /* User data variable */ };
返回值成功返回0失败返回-1
epoll_wait
int epoll_wait(int epfd, struct epoll_event *events, int maxevents, int timeout);
功能监听事件表的事件
参数
epfd文件描述符
events存放实际产生事件的数组空间的首地址
maxevents:最多存放事件的个数
timeout:设定监听的时间超过该时间则不再监听
-1 一直监听直到有事件发生
返回值:
成功返回产生事件的文件描述符个数
失败返回-1
如果时间达到仍没有事件发生返回0
读端
#include head.hint main(void)
{int fd 0;int epfd 0;struct epoll_event env;//epoll_ctl需要的事件的结构体int nready 0;struct epoll_event retenv[2];int i 0;ssize_t nsize 0;char *pret NULL;char tmpbuff[4096] {0};mkfifo(/tmp/myfifo, 0664);fd open(/tmp/myfifo, O_RDONLY);if (-1 fd){perror(fail to open);return -1;}/*创建一张2个事件的内核事件表*/epfd epoll_create(2);if (epfd -1){perror(fail to create);return -1;}/*设置事件结构体的属性*/env.events EPOLLIN;env.data.fd fd;/*操作事件*/epoll_ctl(epfd, EPOLL_CTL_ADD, fd, env);env.events EPOLLIN;env.data.fd 0;epoll_ctl(epfd, EPOLL_CTL_ADD, 0, env);while (1){/*监听事件表中的事件*/nready epoll_wait(epfd, retenv, 2, -1);//第二个参数是存放实际产生事件的结构体, 最多存放的个数, 设置监听时间-1一直监听直到有事件发生if (-1 nready){perror(fail to nready);return -1;}for (i 0; i nready; i){if (retenv[i].data.fd 0)//判断要操作的流是否为从终端输入{memset(tmpbuff, 0, sizeof(tmpbuff));gets(tmpbuff);printf(STDIN: %s\n, tmpbuff);}if (retenv[i].data.fd fd){memset(tmpbuff, 0, sizeof(tmpbuff));read(fd, tmpbuff, sizeof(tmpbuff));printf(FIFO: %s\n, tmpbuff);}}}close(fd);return 0;
}
写端
#include head.hint main(void)
{int fd 0;char tmpbuff[4096] {0};mkfifo(/tmp/myfifo, 0664);fd open(/tmp/myfifo, O_WRONLY);if (-1 fd){perror(fail to open);return -1;}while (1){gets(tmpbuff);write(fd, tmpbuff, strlen(tmpbuff));}close(fd);return 0;
}