epoll笔记

#include <sys/epoll.h>

/*

epoll 很像poll,用于监视多个文件描述符。
epoll既可以是边沿触发,也可以是水位线触发
在epoll实例上注册的文件描述符有时称作epoll集

边沿触发方式时,epoll_wait仍有可能在描述符中有数据可读时挂起,此时,对段可能期待一个回个发送数据的回应。边沿触发只在描述符发生改变时传送信号。所以边沿触发的描述符必须设置为非阻塞的。“with nonblocking file descriptions; and by waiting for an event only after read or write return EAGAIN”
在边沿触发中,信心块的接收产生了各种事件,通过设置EPOLLONESHOT标志来在接收到事件后禁止联合的描述符。指定了EPOLLONESHOT后,调用者必须使用epoll_ctl来重整描述符。
似乎翻译很不到位,原文如下:
Since even with edge-triggered epoll, multiple events can be generateed upon receipt of multiple chunks of data, the caller has the opton to specofy the EPOLLONESHOT flag,
to tell epoll to disable the associate file descriptor after the receipt of an event with epoll_wait. when the EPOLLONESHOT flag is specified, it is the caller;s responsibility to rearm the file descriptor using epoll_ctl with EPOLL_CTL_MOD

水位线触发方式就是一个更加快速的poll, 完全可以替代poll


*/


/*defined events */
enum EPOLL_EVENTS {
    EPOLLIN = 0x001,
#define EPOLLIN EPOLLIN
    EPOLLPRI = 0x002,
#define EPOLLPRI EPOLLPRI
    EPOLLOUT = 0x004,
#define EPOLLOUT EPOLLOUT
    EPOLLRDNORM = 0x040,
#define EPOLLRDNORM EPOLLRDBAND
    EPOLLRDBAND = 0x08,
#define EPOLLRDBAND EPOLLRDBAND
    EPOLLWRNORM = 0x100,
#define EPOLLWRNORM EPOLLWRNORM
    EPOLLWRBAND = 0x200,
#define EPOLLWRBAND EPOLLWRBAND
    EPOLLMSG = 0x400,
#define EPOLLMSG EPOLLMSG
    EPOLLERR = 0x008,
#define EPOLLERR EPOLLERR
    EPOLLHUP = 0x010,
#define EPOLLHUP EPOLLHUP
    EPOLLRDHUP = 0x2000,
#define EPOLLRDHUP EPOLLRDHUP
    EPOLLONESHOT = 1u << 30,
#define EPOLLONESHOT EPLLONESHOT
    EPOLLET = 1u << 31
#define EPOLLET EPOLLET
};

/* valid opcodes ("op" parameter) to issue to epoll_ctl() */
#define EPOLL_CTL_ADD 1  /* add a file description to the interfcae */
#define EPOLL_CTL_DEL 2  /* remove a file description from the interface */
#define EPOLL_CTL_MOD 3  /* change file description epoll_event structure */

typedef union epoll_data {
    void *ptr;
    int fd;
    uint32t u32;
    uint64_t u64;
}epoll_data_t;

struct epoll_event {
    uint32_t events; /* Epoll events */
    epoll_data_t data; /* User data variable */
}__EPOLL_PACKED;

functions

/**
 * creates an epoll instance, return an fd for the new instance. 
 * the size param is a hint specifying the number of file 
 * descriptors to be associated with the new instance. 
 * the fd returned by epoll_create() shoule be closed with 
 * close()
 */
int epoll_create(int __size) __THROW;

/**
 * same as epoll_create but with an flags parameter. the 
 * unused size parameter has been dropped
 */
int epoll_create1(int __flags) __THROW;

/**
 * manipulate an epoll instance "epfd"
 * the op parameter is one of the EPOLL_CTL_* constances 
 * defined above. the fd paramter is the target of the 
 * operation . the event parameter describes which events the 
 * caller is interersted in and any associated user data.
 * return 0 in case of success, -1 in case of error
 */
int epoll_ctl(int __epfd, int __op, int __fd, struct epoll_event *__event) __THROW;


/**
 * wait for events on an epoll instance epfd.
 * the events param is a buffer that will contain triggered 
 * events. the maxevents is the maximum number of events to 
 * be returned (usually size of events). the timeout 
 * parameter specofies the maximum wait time in milliseconds
 * ( -1 == infinite)
 * return the number of triggered events returned in events
 * buffer or -1 in case of error with the errno variable set 
 * to the specific error code
 * 
 * this function is a cancellation point and therefore not 
 * marked with __THROW.
 * 
 * 
 * the data of each rturned structure will contain the same 
 * data the user set with an epoll_ctl(EPOLL_CTL_ADD, 
 * EPOLL_CTL_MOD) while the events member will contain the 
 * returned event bit field.
 */
int epoll_wait(int __epfd, struct epoll_event *__events, int __maxevents, int __timeout);

/**
 * same as epoll_wait, but the thread's signal mask is 
 * temporarily and atomically replaced with the one privided 
 * as prarmeter.
 *
 * this function is a cancellation point and therefore no tmarked with __THROW.
 *
 * epoll_pwait to epoll_wait just like select to pselect.
 * epoll_pwait allows an application to safely wait until 
 * either a file descriptor becomes ready or until a 
 * signal is caught.
 * just as below
 * ready = epoll_wait(epfd, &events, maxevents, timeout, &sigmask);
 * equivalent to atomical executing as following
 * sigset_t origmask;
 * sigprocmask(SIG_SETMASK, &sigmask, &origmask);
 * ready = epoll_wait(epfd, &events, maxevents, timeout);
 * sigprocmask(SIG_SETMASK, &origmask, NULL);

 */
int epoll_pwait(int __epfd, struct epoll_event *__events, int _maxevents, int __timeout, const __sigset_t *__ss);

/**
 * Questions
 * what's cancellation point ?
 */

/*****  Examples *****/
#define MAX_EVENTS 10
struct epoll_event ev, events[MAX_EVENTS];
int listen_sock, conn_sock, nfds, epollfd;

/* ...... */
epollfd = epoll_create(10);
if (epollfd == -1 ){
    perror("epoll_create");
    exit(EXIT_FAILURE);
}

ev.event = EPOLLIN;
ev.data.fd = listen_sock;
if(epoll_ctl(epollfd, EPOLL_CTL_ADD, listen_sock, &ev)) {
    perror("epoll_ctl: listen_sock");
    exit(EXIT_FAILURE);
}

for(;;) {
    nfds = epoll_wait(epollfd, events, MAX_EVENTS, -1);
    if(nfds == -1) {
	perror("epoll_wait");
	exit(EXIT_FAILURE);
    }
    for(n = 0; n < nfds; n ++) {
	if (events[n].data.fd == listen_sock) {
	    conn_sock = accpet(listen_sock, (struct sockaddr *) &local, &addrlen);
	    if(conn_sock == -1 ) {
		perror("accept");
		exit(EXIT_FAILURE);
	    }
	    setnonblocking(conn_sock);
	    ev.events = EPOLLIN | EPOLLET;
	    ev.data.fd = conn_sock;
	    if(epoll_ctl(epollfd, EPOLL_CTL_ADD, conn_sock, &ev) == -1) {
		perror("epoll_ctl: conn_sock");
		exit(EXIT_FAILURE);
	    }
	}
	else {
	    do_use_fd(events[n].data.fd);
	}
    }
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值