各I/O模型 对应Web服务应用模型(select,poll,epoll,kevent,"/dev/poll")
一、利用select多路复用I/O的Web服务应用模型
/* 可读、可写、异常三种文件描述符集的申明和初始化。*/
fd_set readfds, writefds, exceptionfds;
FD_ZERO(&readfds);
FD_ZERO(&writefds);
FD_ZERO(&exceptionfds); int max_fd; /* socket配置和监听。*/
sock = socket(...);
bind(sock, ...);
listen(sock, ...); /* 对socket描述符上发生关心的事件进行注册。*/
FD_SET(&readfds, sock);
max_fd = sock; while() {
int i;
fd_set r,w,e; /* 为了重复使用readfds 、writefds、exceptionfds,将它们拷贝到临时变量内。*/
memcpy(&r, &readfds, sizeof(fd_set));
memcpy(&w, &writefds, sizeof(fd_set));
memcpy(&e, &exceptionfds, sizeof(fd_set)); /* 利用临时变量调用select()阻塞等待,等待时间为永远等待直到发生事件。*/
select(max_fd + , &r, &w, &e, NULL); /* 测试是否有客户端发起连接请求,如果有则接受并把新建的描述符加入监控。*/
if(FD_ISSET(&r, sock)){
new_sock = accept(sock, ...);
FD_SET(&readfds, new_sock);
FD_SET(&writefds, new_sock);
max_fd = MAX(max_fd, new_sock);
}
/* 对其它描述符发生的事件进行适当处理。描述符依次递增,最大值各系统有所不同(比如在作者系统上最大为1024),在linux可以用命令ulimit -a查看(用ulimit命令也对该值进行修改)。在freebsd下,用sysctl -a | grep kern.maxfilesperproc来查询和修改。*/
for(i= sock+; i <max_fd+; ++i) {
if(FD_ISSET(&r, i))
doReadAction(i);
if(FD_ISSET(&w, i))
doWriteAction(i);
}
}
二、利用poll多路复用I/O的Web服务应用模型
/* 新建并初始化文件描述符集。*/
struct pollfd fds[MAX_NUM_FDS];
int max_fd; /* socket配置和监听。*/
sock = socket(...);
bind(sock, ...);
listen(sock, ...); /* 对socket描述符上发生关心的事件进行注册。*/
fds[].fd = sock;
fds[].events = POLLIN;
max_fd = ; while() {
int i; /*调用poll()阻塞等待,等待时间为永远等待直到发生事件。*/
poll(fds, max_fd, -); /* 测试是否有客户端发起连接请求,如果有则接受并把新建的描述符加入监控。*/
if(fds[].revents & POLLIN){
new_sock = accept(sock, ...);
fds[max_fd].fd = new_sock;
fds[max_fd].events = POLLIN | POLLOUT;
++ max_fd;
}
/* 对其它描述符发生的事件进行适当处理。*/
for(i=; i <max_fd+; ++i) {
if(fds.revents & POLLIN)
doReadAction(i);
if(fds.revents & POLLOUT)
doWriteAction(i);
}
} 利用epoll多路复用I/O的Web服务应用模型
/* 新建并初始化文件描述符集。*/
struct epoll_event ev;
struct epoll_event events[MAX_EVENTS]; /* 创建epoll句柄。*/
int epfd = epoll_create(MAX_EVENTS); /* socket配置和监听。*/
sock = socket(...);
bind(sock, ...);
listen(sock, ...); /* 对socket描述符上发生关心的事件进行注册。*/
ev.events = EPOLLIN;
ev.data.fd = sock;
epoll_ctl(epfd, EPOLL_CTL_ADD, sock, &ev); while() {
int i;
/*调用epoll_wait()阻塞等待,等待时间为永远等待直到发生事件。*/
int n = epoll_wait(epfd, events, MAX_EVENTS, -);
for(i=; i <n; ++i) {
/* 测试是否有客户端发起连接请求,如果有则接受并把新建的描述符加入监控。*/
if(events.data.fd == sock) {
if(events.events & POLLIN){
new_sock = accept(sock, ...);
ev.events = EPOLLIN | POLLOUT;
ev.data.fd = new_sock;
epoll_ctl(epfd, EPOLL_CTL_ADD, new_sock, &ev);
}
}else{
/* 对其它描述符发生的事件进行适当处理。*/
if(events.events & POLLIN)
doReadAction(i);
if(events.events & POLLOUT)
doWriteAction(i);
}
}
}
三、利用kqueue多路复用I/O的Web服务应用模型
/* 新建并初始化文件描述符集。*/
struct kevent changelist[MAX_EVENTS];
struct kevent eventlist[MAX_EVENTS];
int count = ; /* 创建kqueue句柄。*/
int kqfd = kqueue(); /* socket配置和监听。*/
sock = socket(...);
bind(sock, ...);
listen(sock, ...); /* 对socket描述符上发生关心的事件进行注册。*/
EV_SET(&changelist[], sock, EVFILT_READ, EV_ADD | EV_ENABLE | EV_CLEAR,
, , );
++ count; while() {
int i;
/*调用kevent()阻塞等待,等待时间为永远等待直到发生事件。*/
int n = kevent(kqfd, changelist, count, eventlist, count, NULL);
for(i=; i <n; ++i) {
/* 测试是否有客户端发起连接请求,如果有则接受并把新建的描述符加入监控。*/
if(eventlist.ident == sock) {
new_sock = accept(sock, ...);
EV_SET(&changelist[count], new_sock, EVFILT_READ,
EV_ADD | EV_ENABLE | EV_CLEAR, , , );
++ count;
}else{
/* 对其它描述符发生的事件进行适当处理。*/
doReadAction(i);
}
}
}
四、利用/dev/poll多路复用I/O的Web服务应用模型
/* 新建并初始化文件描述符集。*/
struct pollfd pfd;
struct pollfd pollfds[MAX_EVENTS];
struct dvpoll dopoll;
int count = ; /* 打开/dev/poll设备,创建poll句柄。*/
int dpfd = open("/dev/poll", O_RDWR); /* socket配置和监听。*/
sock = socket(...);
bind(sock, ...);
listen(sock, ...); /* 对socket描述符上发生关心的事件进行注册。*/
pfd.fd = sock;
pfd.events = EPOLLIN;
pfd.revents = ;
write(dpfd, pfd, sizeof(pfd));
++ count; while() {
int i;
/*调用ioctl()阻塞等待,等待时间为永远等待直到发生事件。*/
dopoll.dp_timeout = -;
dopoll.dp_nfds = count;
dopoll.dp_fds = &pollfds;
int n = ioctl(dpfd, DP_POLL, &dopoll);
for(i=; i <n; ++i) {
/* 测试是否有客户端发起连接请求,如果有则接受并把新建的描述符加入监控。*/
if(pollfds.fd == sock) {
if(pollfds.revents & POLLIN){
new_sock = accept(sock, ...);
pfd.fd = new_sock;
pfd.events = EPOLLIN | POLLOUT;
pfd.revents = ;
write(dpfd, pfd, sizeof(pfd));
++ count;
}
}else{
/* 对其它描述符发生的事件进行适当处理。*/
if(pollfds.revents & POLLIN)
doReadAction(i);
if(pollfds.revents & POLLOUT)
doWriteAction(i);
}
}
}
五、利用rtsig多路复用I/O的Web服务应用模型
/* 新建并初始化关注信号。*/
sigset_t sigset;
siginfo_t siginfo; sigemptyset(&sigset);
sigaddset(&sigset, SIGRTMIN + );
sigaddset(&sigset, SIGIO); /* socket配置和监听。*/
sock = socket(...);
bind(sock, ...);
listen(sock, ...); /* 重新设置描述符可读写时发送的信号值。*/
fcntl(sock, F_SETSIG, SIGRTMIN + ); /* 对socket描述符设置所有者。*/
fcntl(sock, F_SETOWN, getpid()); /* 启用描述符的信号驱动I/O模式。*/
fcntl(sock, F_SETFL, O_ASYNC | O_NONBLOCK | O_RDWR); while() {
struct timespec ts;
ts.tv_sec = ;
ts.tv_nsec = ; /*调用sigtimedwait()阻塞等待,等待时间1秒。*/
sigtimedwait(&sigset, &siginfo, &ts); /* 测试是否有客户端发起连接请求,如果有则接受并把新建的描述符加入监控。*/
if(siginfo.si_fd == sock) {
new_sock = accept(sock, ...);
fcntl(new_sock , F_SETSIG, SIGRTMIN + );
fcntl(new_sock , F_SETOWN, getpid());
fcntl(new_sock , F_SETFL, O_ASYNC | O_NONBLOCK | O_RDWR);
}else {
/* 对其它描述符发生的事件进行适当处理。*/
doReadAction(i);
}
}
各I/O模型 对应Web服务应用模型(select,poll,epoll,kevent,"/dev/poll")的更多相关文章
- EJB_开发EJB容器模型的WEB服务
开发EJB容器模型的WEB服务 WEB服务 Web服务也是一种分布式技术,它与EJB最大的不同是,Web服务属于行业规范,可以跨平台及语言.而EJB属于Java平台的规范,尽管理论上可以跨平台,但实现 ...
- [并发并行]_[线程模型]_[Pthread线程使用模型之三 客户端/服务端模型(Client/Server]
Pthread线程使用模型之三 客户端/服务端模型(Client/Server) 场景 1.在客户端/服务端模型时,客户端向服务端请求一些数据集的操作. 服务端执行执行操作独立的(多进程或跨网络)– ...
- Web服务器之Nginx详解(理论部分)
大纲 一.前言 二.Web服务器提供服务的方式 三.多进程.多线程.异步模式的对比 四.Web 服务请求过程 五.Linux I/O 模型 六.Linux I/O 模型具体说明 七.Linux I/O ...
- 【转】Web服务器之Nginx详解(理论部分)
大纲 一.前言 二.Web服务器提供服务的方式 三.多进程.多线程.异步模式的对比 四.Web 服务请求过程 五.Linux I/O 模型 六.Linux I/O 模型具体说明 七.Linux I/O ...
- 【 Linux 】I/O工作模型及Web服务器原理
一.进程.线程 进程是具有一定独立功能的,在计算机中已经运行的程序的实体.在早期系统中(如linux 2.4以前),进程是基本运作单位,在支持线程的系统中(如windows,linux2.6) ...
- 基于 REST 的 Web 服务:基础
代表性状态传输(Representational State Transfer,REST)在 Web 领域已经得到了广泛的接受,是基于 SOAP 和 Web 服务描述语言(Web Services D ...
- Web服务端软件的服务品质概要
软件品质概述 提供同样功能.产品和服务的服务者中, 竞争力来自功能的多样化和服务品质的差异化, 无论是个体.企业还是国家. 这里的服务指功能.产品的实现程度和处理能力,以及研发/客服提供的技术支持程度 ...
- 【转】简述什么是Web服务(Web Service)技术?
Web Service 是在 Internet 上进行分布式计算的基本构造块,是组件对象技术在 Internet 中的延伸,是一种部署在Web 上的组件.它融合了以组件为基础的开发模式和 ...
- nginx下配置多个web服务
参考 nginx配置详解 nginx反向代理与负载均衡详解 一.nginx简介: Nginx("engine x")是一款是由俄罗斯的程序设计师Igor Sysoev所开发高性能 ...
随机推荐
- 进程通信之一 使用WM_COPYDATA C++及C#实现 z
原文地址:http://blog.csdn.net/morewindows/article/details/6804157 进程间通信最简单的方式就是发送WM_COPYDATA消息.本文提供C++及C ...
- js实现收缩菜单效果
废话不多说,直接上代码: 有注释 <head> <title></title> <style type="text/css"> di ...
- js中的new关键字都干了些什么?
new 操作符 在有上面的基础概念的介绍之后,在加上new操作符,我们就能完成传统面向对象的class + new的方式创建对象,在javascript中,我们将这类方式成为Pseudoclassic ...
- cygwin远程操作linux
远程登录 1.ssh <username>@<IP> eg:ssh root@10.20.30.255 2.输入密码就OK 远程拷贝 1.scp -r <username ...
- 50道经典的JAVA编程题(36-40)
50道经典的JAVA编程题(36-40),今天晚上心情压抑,不爽,继续做题,管它明天考试,我继续我的java,一个周末都在看微机原理看得的很头疼啊~明天该挂科就挂吧,不在乎了~~~ [程序36] Ar ...
- 拉格朗日对偶(Lagrange duality)
拉格朗日对偶(Lagrange duality) 存在等式约束的极值问题求法,比如下面的最优化问题: 目标函数是f(w),下面是等式约束.通常解法是引入拉格朗日算子,这里使用 ...
- JQuery原理
1.简单模拟JQuery工作原理 (function(window){ var JQuery ={ a: function(){ alert('a'); }, b: function(){ alert ...
- hdu1150-Machine Schedule(最小点覆盖)
二分图的最小顶点覆盖:用最少的点,让每条边都至少和其中一个点关联. 最大匹配数 = 最小点覆盖数(Konig 定理) 水题…… 突然发现我以前的匈牙利算法模版有问题……因为这里左边的点时1~n ...
- Codeforces Round #138 (Div. 2) ACBDE
A.Parallelepiped 题意:给一个六面体三面的面积,求12条边的长度和. 题解:因为都是整数,设边长分别为a,b,c,面积为xyz,那么可设x=a*b,y=b*c,z=c*a,简单解方程就 ...
- Java之正则表达式
/* * 正则表达式对字符串的常见操作: * 1.匹配 * * 2.切割 * * 3.替换 * * 4.获取:Pattern p = Pattern.compile(" ...