- 青島雅思—專(zhuān)家談雅思考試發(fā)展趨勢(shì)
- 河南2011上半年自考網(wǎng)上報(bào)名入口 點(diǎn)擊進(jìn)入
- 2011年廣東省護(hù)士資格考試報(bào)名現(xiàn)場(chǎng)確認(rèn)時(shí)間
- 2011上半年樂(lè)山五通橋區(qū)會(huì)計(jì)從業(yè)考試報(bào)名3月10日-4月1
- 哈爾濱香坊區(qū)2011護(hù)士資格考試報(bào)名現(xiàn)場(chǎng)確認(rèn)時(shí)間
- 2011什邡第一次會(huì)計(jì)從業(yè)資格考試報(bào)名3月1日-4月15日
- 2011什邡第二次會(huì)計(jì)從業(yè)資格考試報(bào)名7月1日-9月16日
- 2011年中山市護(hù)士資格考試報(bào)名工作的通知
- 長(zhǎng)安大學(xué)2011考研成績(jī)查詢(xún)?nèi)肟?點(diǎn)擊進(jìn)入
- 西華大學(xué)2011考研成績(jī)查詢(xún)?nèi)肟?點(diǎn)擊進(jìn)入
- 中國(guó)地質(zhì)大學(xué)(武漢)2011考研成績(jī)3月3日查詢(xún)
- 中南民族大學(xué)2011考研成績(jī)查詢(xún)3月4日開(kāi)始
- 沈陽(yáng)建筑大學(xué)2011考研成績(jī)查詢(xún)?nèi)肟?點(diǎn)擊進(jìn)入
- 沈陽(yáng)工業(yè)大學(xué)2011考研成績(jī)查詢(xún)?nèi)肟?點(diǎn)擊進(jìn)入
【武漢華嵌】poll和select的使用和差異
來(lái)源:求學(xué)問(wèn)校網(wǎng) 發(fā)表時(shí)間:2011-10-26 瀏覽 68 次
作者:武漢華嵌技術(shù)部
使用非阻塞I/O 的應(yīng)用程序常常使用poll, select。poll和select本質(zhì)上有相同的功能:每個(gè)允許一個(gè)進(jìn)程來(lái)決定它是否可讀或者寫(xiě)一個(gè)或多個(gè)文件而不阻塞。這些調(diào)用也可阻塞進(jìn)程直到任何一個(gè)給定集合的文件描述符可用來(lái)讀或?qū)?。因此,它們常常用在必須使用多輸入輸出流的?yīng)用程序,而不必粘連在它們?nèi)魏我粋€(gè)上. 相同的功能常常由多個(gè)函數(shù)提供,因?yàn)? 個(gè)是由不同的團(tuán)隊(duì)在幾乎相同時(shí)間完成的:select 在BSD Unix 中引入,而poll 是System V 的解決方案。
那么以下分別來(lái)分析下select和poll的各自用法。
首先來(lái)分析下select:
1、函數(shù)原型如下:
#include <sys/select.h>
int select(int maxfdp1, fd_set *restrict readfds,
fd_set *restrict writefds, fd_set *restrict exceptfds,
struct timeval *restrict tvptr);
2、select做了些什么?分兩次來(lái)講:
⑴、傳向select的參數(shù)告知內(nèi)核,我們所關(guān)心的描述符;對(duì)于每個(gè)描述符我們所關(guān)心的狀態(tài);愿意等待多長(zhǎng)時(shí)間。
⑵、select返回時(shí),內(nèi)核告訴我們已經(jīng)準(zhǔn)備好的描述符的數(shù)量;對(duì)于讀、寫(xiě)或異常這三個(gè)狀態(tài)中的每一個(gè),哪里些描述符已經(jīng)準(zhǔn)備好。
3、select函數(shù)參數(shù)分析:
⑴最后一個(gè)參數(shù),它指定愿意等待的時(shí)間。
struct timeval{
long tv_sec; //seconds
long tv_usec; //and microseconds
};
tvptr == NULL時(shí),永遠(yuǎn)等待。
tvptr->tv_sec == 0 && tvptr->tv_usec == 0時(shí),完全不等待。
tvptr->tv_sec != 0 || tvptr->tv_usec != 0時(shí),等待指定的秒數(shù)和微秒數(shù)。
⑵、中間的三個(gè)參數(shù)readfds、writefds、exceptfds是指向描述符集的指針。這三個(gè)參數(shù)描述符集說(shuō)明了我們關(guān)心的可讀、可寫(xiě)或處于異常條件的各個(gè)描述符。每個(gè)描述符集存放在一個(gè)fd_set數(shù)據(jù)類(lèi)型中。這各數(shù)據(jù)類(lèi)型為每一可能的描述符保持了一個(gè)bit位。
對(duì)fd_set數(shù)據(jù)類(lèi)型可以進(jìn)行的處理是:分配一個(gè)這種類(lèi)型的變量;將這種類(lèi)型的一個(gè)變量值賦予同類(lèi)型的另一個(gè)變量;或?qū)τ谶@種類(lèi)型的變量使用下列四個(gè)函數(shù)中的一個(gè)。
#include <sys/select.h>
int FD_ISSET(int fd, fd_set *fdset);
返回值:若fd在描述符集中則返回非0值,否則返回0。
void FD_CLR(int fd, fd_set *fdset);
void FD_SET(int fd, fd_set *fdset);
void FD_ZERO(fd_set *fdset);
以上這些接口的作用分別是:FD_ZERO將一個(gè)指定的fd_set變量的所有位設(shè)置為0。FD_SET設(shè)置一個(gè)fd_set變量的指定位。FD_CLR將一指定位清除。FD_ISSET測(cè)試一指定位是否設(shè)置。
這三個(gè)參數(shù)中的任意一個(gè)或全部都可以是空指針,這表示對(duì)相應(yīng)狀態(tài)并不關(guān)心。如果所有三個(gè)指針都是空指針,則select提供了較sleep更精確的計(jì)時(shí)器。
⑶、第一個(gè)參數(shù)maxfdp1的意思是“最大描述符加1”。在三個(gè)描述符集中找到最大描述符編號(hào)值,然后加1,這就是第一個(gè)參數(shù)。
4、select返回值分析:
⑴、返回-1,表示出錯(cuò)。
⑵、返回0,表示沒(méi)有描述符準(zhǔn)備好。若指定的描述符都沒(méi)有準(zhǔn)備好,而且指定的時(shí)間已經(jīng)超過(guò),則發(fā)生這種情況。此時(shí),所有描述符集皆被清0。
⑶、正返回值表示已經(jīng)準(zhǔn)備好的描述符數(shù),該值是三個(gè)描述符集中已經(jīng)準(zhǔn)備好的描述符數(shù)之和,所以如果同一描述符已經(jīng)準(zhǔn)備好讀和寫(xiě),那么在返回值班中將其計(jì)為2.在這種情況下,三個(gè)描述符集中仍舊打開(kāi)的位對(duì)應(yīng)于已經(jīng)準(zhǔn)備好的描述符。
5、select使用的片段代碼如下:
fd_set inset, tmp_inset;//聲名兩個(gè)描述符集
FD_ZERO(&inset);//清0
FD_SET(sockfd, &inset);//設(shè)置sockfd的指定位
if (!(select(MAX_SOCK_FD, &tmp_inset, NULL, NULL, NULL) > 0))
//在這里等著,等到描述符集中的任何一個(gè)描述符有反應(yīng)了,就返回、、//正值
{
perror("select");
close(sockfd);
exit(1);
}
分析完select,現(xiàn)在分析下poll:
函數(shù)原型如下:
#include <poll.h>
int poll(struct pollfd fdarray[], nfds_t nfds, int timeout);
poll函數(shù)參數(shù)分析:
⑴最后一個(gè)參數(shù),它指定愿意等待的時(shí)間。
timeout == -1時(shí),永遠(yuǎn)等待。
timeout == 0時(shí),不等待。
timeout > 0時(shí),等待timeout毫秒。(如果系統(tǒng)不提供望毫秒分辨,則timeout值取整到最近的支持值)
⑵與select不同,poll不是為每個(gè)狀態(tài)構(gòu)造一個(gè)描述符集,面是構(gòu)造一個(gè)pollfd結(jié)構(gòu)數(shù)組,每個(gè)數(shù)組元素指定一個(gè)描述符編號(hào)以及對(duì)其所關(guān)心的狀態(tài)。pollfd結(jié)構(gòu)如下:
struct pollfd{
int fd; //file descriptor to check, or < 0 to ignore
short events; //events of interest on fd
short revents;//events that occurred on fd
};
應(yīng)將每個(gè)數(shù)組元素的events成員設(shè)置如下表的值。通過(guò)這些值告訴內(nèi)核我們對(duì)該描述符關(guān)心的產(chǎn)什么。返回時(shí),內(nèi)核設(shè)置revents成員,以說(shuō)明對(duì)于該描述符已經(jīng)發(fā)生了什么事件。
標(biāo)志名
輸入至
events?
從revents得到結(jié)果?
說(shuō)明
POLLIN
Yes
Yes
不阻塞地可讀除高優(yōu)先級(jí)外的數(shù)據(jù)
POLLRDNORM
Yes
Yes
不阻塞地可讀普通數(shù)據(jù)
POLLRDBAND
Yes
Yes
不阻塞地可讀非0優(yōu)先級(jí)波段數(shù)據(jù)
POLLPRI
Yes
Yes
不阻塞地可讀高優(yōu)先級(jí)數(shù)據(jù)
POLLOUT
Yes
Yes
不阻塞地可寫(xiě)普通數(shù)據(jù)
POLLWRNORM
Yes
Yes
與POLLOUT相同
POLLWRBAND
Yes
Yes
不阻塞的可寫(xiě)非0優(yōu)先級(jí)波段數(shù)據(jù)
POLLERR
Yes
已出錯(cuò)
POLLHUP
Yes
已掛斷
POLLNVAL
Yes
描述符不引用一打開(kāi)文件
⑶nfds說(shuō)明fdarray數(shù)組中的元素?cái)?shù)。
poll返回值分析:
⑴、返回0時(shí),超時(shí)返回。
⑵、返回-1時(shí),出錯(cuò)返回。
⑶、返回正值時(shí),表示準(zhǔn)備就緒的描述符數(shù)。
poll使用的片段代碼如下:
struct pollfd pollfds[1]; //聲明一個(gè)struct pollfd結(jié)構(gòu)數(shù)組
pollfds[0].fd = fd ; //初始化struct pollfd數(shù)組第0個(gè)元素成員
pollfds[0].events = POLLIN;//初始化對(duì)該描述符所關(guān)心的
while (!terminate) {
if (poll(pollfds, 1, 100) <= 0)/*正常返回,得到的是準(zhǔn)備就緒的描述符數(shù)。如果時(shí)間到了還沒(méi)有描述符有反應(yīng),那么就返回-1,結(jié)束本次循環(huán)。*/
continue;
……………
……………
}
注意:
執(zhí)行select后,如果成功了,其改變了描述符集中的內(nèi)容,也就讓沒(méi)有反應(yīng)的描述符位清0。而poll在執(zhí)行結(jié)束后,并沒(méi)有改變events中的內(nèi)容,而是把執(zhí)行的事件設(shè)置給revents來(lái)告知客戶(hù)。
使用非阻塞I/O 的應(yīng)用程序常常使用poll, select。poll和select本質(zhì)上有相同的功能:每個(gè)允許一個(gè)進(jìn)程來(lái)決定它是否可讀或者寫(xiě)一個(gè)或多個(gè)文件而不阻塞。這些調(diào)用也可阻塞進(jìn)程直到任何一個(gè)給定集合的文件描述符可用來(lái)讀或?qū)?。因此,它們常常用在必須使用多輸入輸出流的?yīng)用程序,而不必粘連在它們?nèi)魏我粋€(gè)上. 相同的功能常常由多個(gè)函數(shù)提供,因?yàn)? 個(gè)是由不同的團(tuán)隊(duì)在幾乎相同時(shí)間完成的:select 在BSD Unix 中引入,而poll 是System V 的解決方案。
那么以下分別來(lái)分析下select和poll的各自用法。
首先來(lái)分析下select:
1、函數(shù)原型如下:
#include <sys/select.h>
int select(int maxfdp1, fd_set *restrict readfds,
fd_set *restrict writefds, fd_set *restrict exceptfds,
struct timeval *restrict tvptr);
2、select做了些什么?分兩次來(lái)講:
⑴、傳向select的參數(shù)告知內(nèi)核,我們所關(guān)心的描述符;對(duì)于每個(gè)描述符我們所關(guān)心的狀態(tài);愿意等待多長(zhǎng)時(shí)間。
⑵、select返回時(shí),內(nèi)核告訴我們已經(jīng)準(zhǔn)備好的描述符的數(shù)量;對(duì)于讀、寫(xiě)或異常這三個(gè)狀態(tài)中的每一個(gè),哪里些描述符已經(jīng)準(zhǔn)備好。
3、select函數(shù)參數(shù)分析:
⑴最后一個(gè)參數(shù),它指定愿意等待的時(shí)間。
struct timeval{
long tv_sec; //seconds
long tv_usec; //and microseconds
};
tvptr == NULL時(shí),永遠(yuǎn)等待。
tvptr->tv_sec == 0 && tvptr->tv_usec == 0時(shí),完全不等待。
tvptr->tv_sec != 0 || tvptr->tv_usec != 0時(shí),等待指定的秒數(shù)和微秒數(shù)。
⑵、中間的三個(gè)參數(shù)readfds、writefds、exceptfds是指向描述符集的指針。這三個(gè)參數(shù)描述符集說(shuō)明了我們關(guān)心的可讀、可寫(xiě)或處于異常條件的各個(gè)描述符。每個(gè)描述符集存放在一個(gè)fd_set數(shù)據(jù)類(lèi)型中。這各數(shù)據(jù)類(lèi)型為每一可能的描述符保持了一個(gè)bit位。
對(duì)fd_set數(shù)據(jù)類(lèi)型可以進(jìn)行的處理是:分配一個(gè)這種類(lèi)型的變量;將這種類(lèi)型的一個(gè)變量值賦予同類(lèi)型的另一個(gè)變量;或?qū)τ谶@種類(lèi)型的變量使用下列四個(gè)函數(shù)中的一個(gè)。
#include <sys/select.h>
int FD_ISSET(int fd, fd_set *fdset);
返回值:若fd在描述符集中則返回非0值,否則返回0。
void FD_CLR(int fd, fd_set *fdset);
void FD_SET(int fd, fd_set *fdset);
void FD_ZERO(fd_set *fdset);
以上這些接口的作用分別是:FD_ZERO將一個(gè)指定的fd_set變量的所有位設(shè)置為0。FD_SET設(shè)置一個(gè)fd_set變量的指定位。FD_CLR將一指定位清除。FD_ISSET測(cè)試一指定位是否設(shè)置。
這三個(gè)參數(shù)中的任意一個(gè)或全部都可以是空指針,這表示對(duì)相應(yīng)狀態(tài)并不關(guān)心。如果所有三個(gè)指針都是空指針,則select提供了較sleep更精確的計(jì)時(shí)器。
⑶、第一個(gè)參數(shù)maxfdp1的意思是“最大描述符加1”。在三個(gè)描述符集中找到最大描述符編號(hào)值,然后加1,這就是第一個(gè)參數(shù)。
4、select返回值分析:
⑴、返回-1,表示出錯(cuò)。
⑵、返回0,表示沒(méi)有描述符準(zhǔn)備好。若指定的描述符都沒(méi)有準(zhǔn)備好,而且指定的時(shí)間已經(jīng)超過(guò),則發(fā)生這種情況。此時(shí),所有描述符集皆被清0。
⑶、正返回值表示已經(jīng)準(zhǔn)備好的描述符數(shù),該值是三個(gè)描述符集中已經(jīng)準(zhǔn)備好的描述符數(shù)之和,所以如果同一描述符已經(jīng)準(zhǔn)備好讀和寫(xiě),那么在返回值班中將其計(jì)為2.在這種情況下,三個(gè)描述符集中仍舊打開(kāi)的位對(duì)應(yīng)于已經(jīng)準(zhǔn)備好的描述符。
5、select使用的片段代碼如下:
fd_set inset, tmp_inset;//聲名兩個(gè)描述符集
FD_ZERO(&inset);//清0
FD_SET(sockfd, &inset);//設(shè)置sockfd的指定位
if (!(select(MAX_SOCK_FD, &tmp_inset, NULL, NULL, NULL) > 0))
//在這里等著,等到描述符集中的任何一個(gè)描述符有反應(yīng)了,就返回、、//正值
{
perror("select");
close(sockfd);
exit(1);
}
分析完select,現(xiàn)在分析下poll:
函數(shù)原型如下:
#include <poll.h>
int poll(struct pollfd fdarray[], nfds_t nfds, int timeout);
poll函數(shù)參數(shù)分析:
⑴最后一個(gè)參數(shù),它指定愿意等待的時(shí)間。
timeout == -1時(shí),永遠(yuǎn)等待。
timeout == 0時(shí),不等待。
timeout > 0時(shí),等待timeout毫秒。(如果系統(tǒng)不提供望毫秒分辨,則timeout值取整到最近的支持值)
⑵與select不同,poll不是為每個(gè)狀態(tài)構(gòu)造一個(gè)描述符集,面是構(gòu)造一個(gè)pollfd結(jié)構(gòu)數(shù)組,每個(gè)數(shù)組元素指定一個(gè)描述符編號(hào)以及對(duì)其所關(guān)心的狀態(tài)。pollfd結(jié)構(gòu)如下:
struct pollfd{
int fd; //file descriptor to check, or < 0 to ignore
short events; //events of interest on fd
short revents;//events that occurred on fd
};
應(yīng)將每個(gè)數(shù)組元素的events成員設(shè)置如下表的值。通過(guò)這些值告訴內(nèi)核我們對(duì)該描述符關(guān)心的產(chǎn)什么。返回時(shí),內(nèi)核設(shè)置revents成員,以說(shuō)明對(duì)于該描述符已經(jīng)發(fā)生了什么事件。
標(biāo)志名
輸入至
events?
從revents得到結(jié)果?
說(shuō)明
POLLIN
Yes
Yes
不阻塞地可讀除高優(yōu)先級(jí)外的數(shù)據(jù)
POLLRDNORM
Yes
Yes
不阻塞地可讀普通數(shù)據(jù)
POLLRDBAND
Yes
Yes
不阻塞地可讀非0優(yōu)先級(jí)波段數(shù)據(jù)
POLLPRI
Yes
Yes
不阻塞地可讀高優(yōu)先級(jí)數(shù)據(jù)
POLLOUT
Yes
Yes
不阻塞地可寫(xiě)普通數(shù)據(jù)
POLLWRNORM
Yes
Yes
與POLLOUT相同
POLLWRBAND
Yes
Yes
不阻塞的可寫(xiě)非0優(yōu)先級(jí)波段數(shù)據(jù)
POLLERR
Yes
已出錯(cuò)
POLLHUP
Yes
已掛斷
POLLNVAL
Yes
描述符不引用一打開(kāi)文件
⑶nfds說(shuō)明fdarray數(shù)組中的元素?cái)?shù)。
poll返回值分析:
⑴、返回0時(shí),超時(shí)返回。
⑵、返回-1時(shí),出錯(cuò)返回。
⑶、返回正值時(shí),表示準(zhǔn)備就緒的描述符數(shù)。
poll使用的片段代碼如下:
struct pollfd pollfds[1]; //聲明一個(gè)struct pollfd結(jié)構(gòu)數(shù)組
pollfds[0].fd = fd ; //初始化struct pollfd數(shù)組第0個(gè)元素成員
pollfds[0].events = POLLIN;//初始化對(duì)該描述符所關(guān)心的
while (!terminate) {
if (poll(pollfds, 1, 100) <= 0)/*正常返回,得到的是準(zhǔn)備就緒的描述符數(shù)。如果時(shí)間到了還沒(méi)有描述符有反應(yīng),那么就返回-1,結(jié)束本次循環(huán)。*/
continue;
……………
……………
}
注意:
執(zhí)行select后,如果成功了,其改變了描述符集中的內(nèi)容,也就讓沒(méi)有反應(yīng)的描述符位清0。而poll在執(zhí)行結(jié)束后,并沒(méi)有改變events中的內(nèi)容,而是把執(zhí)行的事件設(shè)置給revents來(lái)告知客戶(hù)。
武漢電腦培訓(xùn)培訓(xùn)相關(guān)新聞
武漢電腦培訓(xùn)相關(guān)課程
- 襄陽(yáng)室內(nèi)設(shè)計(jì)培訓(xùn)學(xué)校
- 襄陽(yáng)廣告設(shè)計(jì)培訓(xùn)學(xué)校
- 襄陽(yáng)辦公文秘培訓(xùn)襄陽(yáng)辦公應(yīng)用培訓(xùn)
- 襄陽(yáng)園林景觀(guān)設(shè)計(jì)培訓(xùn)學(xué)校
- 襄陽(yáng)建筑cad培訓(xùn)襄陽(yáng)室內(nèi)cad培訓(xùn)襄陽(yáng)家俱cad培訓(xùn)
- 襄陽(yáng)建筑cad培訓(xùn)室內(nèi)cad培訓(xùn)
- 襄陽(yáng)機(jī)械cad培訓(xùn)
- 襄陽(yáng)2020年全國(guó)計(jì)算機(jī)等級(jí)考試報(bào)名和培訓(xùn)
- 襄陽(yáng)建筑設(shè)計(jì)培訓(xùn)學(xué)校
- 襄陽(yáng)3dmax培訓(xùn)襄陽(yáng)cad培訓(xùn)襄陽(yáng)vray培訓(xùn)襄陽(yáng)ps培訓(xùn)
- 襄陽(yáng)網(wǎng)頁(yè)設(shè)計(jì)培訓(xùn)襄陽(yáng)網(wǎng)站制作培訓(xùn)
- 襄陽(yáng)影視廣告動(dòng)漫設(shè)計(jì)培訓(xùn)
- 襄陽(yáng)大眾室內(nèi)設(shè)計(jì)培訓(xùn)高級(jí)學(xué)校
- 襄陽(yáng)家具Cad培訓(xùn)襄陽(yáng)室內(nèi)Cad培訓(xùn)
武漢電腦培訓(xùn)相關(guān)機(jī)構(gòu)
武漢最新資訊
- 青島雅思—專(zhuān)家談雅思考試發(fā)展趨勢(shì)
- 河南2011上半年自考網(wǎng)上報(bào)名入口 點(diǎn)…
- 2011年廣東省護(hù)士資格考試報(bào)名現(xiàn)場(chǎng)確…
- 2011上半年樂(lè)山五通橋區(qū)會(huì)計(jì)從業(yè)考試…
- 哈爾濱香坊區(qū)2011護(hù)士資格考試報(bào)名現(xiàn)…
- 2011什邡第一次會(huì)計(jì)從業(yè)資格考試報(bào)名…
- 2011什邡第二次會(huì)計(jì)從業(yè)資格考試報(bào)名…
- 2011年中山市護(hù)士資格考試報(bào)名工作的…
- 長(zhǎng)安大學(xué)2011考研成績(jī)查詢(xún)?nèi)肟?點(diǎn)擊…
- 西華大學(xué)2011考研成績(jī)查詢(xún)?nèi)肟?點(diǎn)擊…
武漢推薦課程導(dǎo)航
雅思 | 口語(yǔ) | 日語(yǔ) | 韓語(yǔ) | 德語(yǔ) | 四六級(jí) | 商務(wù)英語(yǔ) | 平面設(shè)計(jì) | 游戲動(dòng)漫 | 影視制作 | 室內(nèi)外設(shè)計(jì) | 動(dòng)畫(huà)設(shè)計(jì) | 網(wǎng)頁(yè)設(shè)計(jì) | 等級(jí)考試軟件工程 | 美容培訓(xùn) | 手機(jī)維修 | 廚師面點(diǎn) | 會(huì)計(jì)職稱(chēng) | 心理咨詢(xún) | 人力資源