標籤:
參考:http://www.cnblogs.com/Anker/p/3265058.html
select
/* According to POSIX.1-2001 */ #include <sys/select.h> /* According to earlier standards */ #include <sys/time.h> #include <sys/types.h> #include <unistd.h> int select(int nfds, fd_set *readfds, fd_set *writefds, fd_set *exceptfds, struct timeval *timeout); void FD_CLR(int fd, fd_set *set); int FD_ISSET(int fd, fd_set *set); void FD_SET(int fd, fd_set *set); void FD_ZERO(fd_set *set); #include <sys/select.h> int pselect(int nfds, fd_set *readfds, fd_set *writefds, fd_set *exceptfds, const struct timespec *timeout, const sigset_t *sigmask);
select例子
#include <stdio.h> #include <stdlib.h> #include <sys/time.h> #include <sys/types.h> #include <unistd.h> int main(void) { fd_set rfds; struct timeval tv; int retval; /* Watch stdin (fd 0) to see when it has input. */ FD_ZERO(&rfds); FD_SET(0, &rfds); /* Wait up to five seconds. */ tv.tv_sec = 5; tv.tv_usec = 0; retval = select(1, &rfds, NULL, NULL, &tv); /* Don‘t rely on the value of tv now! */ if (retval == -1) perror("select()"); else if (retval) printf("Data is available now.\n"); /* FD_ISSET(0, &rfds) will be true. */ else printf("No data within five seconds.\n"); exit(EXIT_SUCCESS); }View Code
優點:實現簡單,執行效率高,相容性好,當描述符集合活躍度較高時,效能可能優於epoll。
select的幾大缺點:
(1)每次調用select,都需要把fd集合從使用者態拷貝到核心態,這個開銷在fd很多時會很大
(2)同時每次調用select都需要在核心遍曆傳遞進來的所有fd,這個開銷在fd很多時也很大
(3)select支援的檔案描述符數量太小了,預設是1024
poll
#include <poll.h> int poll(struct pollfd *fds, nfds_t nfds, int timeout);
功能和select類似,介面不同,優缺點和select類似,解決了select的缺點(3)
epoll
#include <sys/epoll.h> int epoll_create(int size); int epoll_ctl(int epfd, int op, int fd, struct epoll_event *event); int epoll_wait(int epfd, struct epoll_event *events, int maxevents, int timeout); int epoll_pwait(int epfd, struct epoll_event *events, int maxevents, int timeout, const sigset_t *sigmask);
優點:解決了select的三個缺點,適合並發量大,活躍量小的情況下。
缺點:epoll實現複雜一些。
epoll_create:建立epoll控制代碼,返回epoll對應的檔案描述符epfd。linux 2.6.8之後,size被忽略,大於0即可。出錯,-1,errno;
epoll_ctl:
op:
EPOLL_CTL_ADD:添加fd;
EPOLL_CTL_MOD:修改*event;
EPOLL_CTL_DEL:刪除fd,*event忽略,可為NULL;
*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 */ };
events:
- EPOLLIN 對應檔案可讀
- EPOLLOUT 對應檔案可寫
- EPOLLRDHUP (since Linux 2.6.17) 流通訊端對等關閉串連或寫半關閉
- EPOLLPRI 有緊急資料可讀
- EPOLLERR 檔案描述符出錯,epoll_wait總是監聽此事件,不需要設定
- EPOLLHUP 檔案描述符掛起,epoll_wait總是監聽此事件,不需要設定
- EPOLLET 設定 ET 模式,預設 LT 模式
- EPOLLONESHOT (since Linux 2.6.2) 只監聽一次事件,監聽完成這次事件後,不再監聽,若需要,可再次epoll_ctl加入
epoll_wait:監聽epfd中的事件
*events:儲存發生時間;
maxevents:大於0,傳回值最大不超過此值;
timeout:逾時設定;
select,poll,epoll之api筆記