如何处理多路并发请求?
通常有以下5种方法:
1> 每个请求,fork一个子进程进行处理
2> 每个请求,创建一个子线程进行处理
3> select
4> poll
5> epoll
方法1:
accept请求后,执行fork()创建子进程。
pid = fork();
if (pid == -1) {
//错误处理
}
if (pid == 0) {
// 父进程
continue;
}
// 子进程
// 处理请求
方法2:
accept请求后,执行pthread_create创建子线程
方法3:
fd_set rx_socks; // 接收监控集
fd_set wk_socks; // 处理监控集
// 初始化
FD_ZERO(&rx_socks);
FD_ZERO(&wk_socks);
FD_SET(s, &read_socks); //将Server端Socket放入接收监控集
maxFD = s + 1;
for (;;) {
// 每次调用select前,重新初始化监控集
FD_ZERO(&wk_socks);
for ( i = 0; i < maxFD; ++i) {
if (FD_ISSET(i, &rx_socks)) {
FD_SET(i, &wk_socks);
}
}
// 设置超时信息
timeOut.tv_sec = 5;
timeOut.tv_usec = 0;
n = select(mx, &wk_socks, NULL, NULL, &timeOut);
if (n == -1) {
// 错误处理
}
if ( n == 0) {
// 超时处理
}
if ( FD_ISSET(s, &wk_socks)) { // 有Request
调用accept,并将sock放入rx_socks
if ( c + 1 > mx) { //更新监控fd范围
mx = c +1;
}
}
// 依次检查wk_socks是否有事件需要处理
for ( c=0; c< mx; ++c) {
if ( c== s) {
continue;
}
if ( FD_ISSET(c, &wK_socks)) {
//处理客户端消息
// 如果客户端结束,则将其从rx_socks清除( FD_CLR(c, &rx_set))
}
}
// 重新检查rx_socks,修正监控范围
for (c = mx -1; (c>=0) && (!FD_ISSET(c, &rx_set)); c = c -1)
mx = c;
}
select方法的核心是对每个监控fd进行轮训检查,如果有事件,则相应标志位设为1.
限制: 最多支持FD_SETSIZE(通常为1024)个并发请求。4> poll
select与poll区别可以用下面例子来简单说明:
假设有一些同学来到了某个教室上课,老师如何知道哪些学生想提问?
select: 记录进入教室的学生的最大学号,从0到最大学号,依次轮训检查是否有问题要问,有的话就
设置为1.(明显没来教室的肯定也询问了一次, 性能浪费)
poll: 用一个记事本记录所有来教室上课的学生学号,然后依次询问该学生是否有问题要问。
接口:
#include <sys/poll.h>
struct pollfd {
int fd; /* 文件描述符 */
short events; /* 等待的事件 */
short revents; /* 实际发生了的事件 */
};
int poll ( struct pollfd * fds, unsigned int nfds, int timeout);
使用poll就简单了,我们先将server 监控socket作为第一个元素放入
pollfd 数组中,然后调用poll,如果有request(对应POLLIN)事件,则执行
accept,并将新的连接fd放入pollfd 数组中。
缺点: 维护pollfd数组远比bit位占用更多内存,用户态与内核态交互的数据拷贝负荷大。
顾名思义,用阻塞event机制代替轮训poll,对poll进行了改进。
接口:
epoll_create 初始化
epoll_ctl 对监控队列进行操作
epoll_wait 阻塞,等待事件通知
参考代码:
http://www.cnblogs.com/ggjucheng/archive/2012/01/17/2324974.html
关于select / poll /epoll的分析比较可以参考以下博客:
http://blog.sina.com.cn/s/blog_8fa7dd41010153zx.html
个人项目体会,一般情况下用select,高连接(>5000)下用epoll。
Linux Socket Programming by Example-第十一章 多客户端并发处理,布布扣,bubuko.com