为了理解一下epoll的读写事件如何触发,自己写了一些测试程序。
Example 1:
#include <strings.h>
#include <sys/socket.h>
#include <sys/epoll.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <fcntl.h>
#include <unistd.h>
#include <stdio.h>
#include <stdlib.h>
#include <errno.h>
#define MAXLINE 10
#define OPEN_MAX 100
#define LISTENQ 20
#define SERV_PORT 8080
#define INFTIM 1000
void setnonblocking(int sock)
{
int opts;
opts=fcntl(sock,F_GETFL);
if(opts<0)
{
perror("fcntl(sock,GETFL)");
exit(1);
}
opts = opts|O_NONBLOCK;
if(fcntl(sock,F_SETFL,opts)<0)
{
perror("fcntl(sock,SETFL,opts)");
exit(1);
}
}
int main()
{
int epfd,nfds;
char line[MAXLINE];
//声明epoll_event结构体的变量,ev用于注册事件,数组用于回传要处理的事件
struct epoll_event ev,events[20];
//生成用于处理accept的epoll专用的文件描述符
epfd=epoll_create(256);
int rfd, wfd, pipefd[2];
if (pipe(pipefd) == -1) {
perror("pipe");
exit(1);
}
rfd = pipefd[0];
wfd = pipefd[1];
ev.data.fd = rfd;
ev.events = EPOLLIN | EPOLLET;
epoll_ctl(epfd, EPOLL_CTL_ADD, rfd, &ev);
ev.data.fd = wfd;
ev.events = EPOLLOUT | EPOLLET;
epoll_ctl(epfd, EPOLL_CTL_ADD, wfd, &ev);
printf("rfd: %d, wfd: %d\n", rfd, wfd);
setnonblocking(rfd);
setnonblocking(wfd);
/* #######code insertion point###### */
for ( ; ; ) {
int nevents = epoll_wait(epfd, events, 20, 0);
printf("%d events\n", nevents); if (nevents == 0) continue;
for (int i=0; i<nevents; i++) {
if (events[i].events & EPOLLIN) {
printf("fd %d is available to read\n", events[i].data.fd);
sleep(1);
}
else if (events[i].events & EPOLLOUT) {
printf("fd %d is available to write\n", events[i].data.fd);
sleep(1);
}
}
}
return 0;
}
Case 1: 在代码插入点 不插入任何程序时,
Output:
rfd: 4, wfd: 5
1 events
fd 5 is available to write
在