select poll 在應用程式中如何使用

2021-05-26 08:15:30 字數 4235 閱讀 7964

select()

和poll()

系統呼叫的本質一樣,前者在

bsd unix

中引入的,後者在

system v

中引入的。

一、select

應用程式中最廣泛用到的是

bsd unix

中引入的

select()

系統呼叫,其原型如下:

int select(int maxfdp, fd_set *readfds, fd_set *writefds, fd_set *errorfds, struct timeval *timeout);

select

的第乙個引數

maxfdp

是檔案描述符集中要被檢測的數目,這個值必須至少比待檢測的最大檔案描述符大1;

引數readfds

指定了需要被讀監測的檔案描述符集;引數

writefds

指定了需要被寫監測的檔案描述符集;而引數

errorfds

指定了可能出現異常情況的檔案描述符集。

timeout

引數是乙個指向

struct timeval

型別的指標,它可以使

select()

在等待timeout

時間後若沒有檔案描述符準備好則返回。

struct timeval

資料結構的定義如下:

struct timeval

;timeout

取不同的值,該呼叫就表現不同的性質: 1

.timeout為0

,呼叫立即返回; 2

.timeout

為null

,select()

呼叫就阻塞,直到知道有檔案描述符就緒;

(當有檔案描述符就緒時,會向這個函式傳送訊號,以喚醒此函式。)

3.timeout

為正整數,就是一般的定時器。

select

的返回值有如下情況: 1

.正常情況下返回就緒的檔案描述符個數; 2

.經過了

timeout

時長後仍無裝置準備好,返回值為0;

3.如果select

被某個訊號中斷,它將返回

-1並設定

errno

為eintr。

4.如果出錯,返回

-1並設定相應的

errno

。select()

函式的介面主要是建立在一種叫

fd_set

結構體的基礎上。這個結構體是一組檔案描述符(

fd)的集合。因為

fd_set

型別的長度在不同平台上是不同的,此應該用一組標準的巨集定義來處理這個類變數。

我們來了解

fd_set

這個結構的定義:

typedef struct __kernel_fd_set;

#define __nfdbits       (8 * sizeof(unsigned long)) //32

#define __fd_setsize    1024//

每個程序能開啟的檔案描述符的上限,可以更改

#define __fdset_longs   (__fd_setsize/__nfdbits)// 32

typedef __kernel_fd_set         fd_set;

對用fd_set

定義的readfds

、writefds

、errorfds

操作集進行操作最好使用封裝的通用巨集來處理:

fd_zero(fd_set *set);//

將檔案描述符集

fd_set

中的值置

0,如此以來對應所有位都被設定為0;

fd_set(int fd,fd_set *set);//

將乙個檔案描述符加入檔案描述集中;

fd_clr(int fd,fd_set *set)//

將乙個檔案描述符從檔案描述符集中清除;

fd_isset(int fd,fd_set *set)//

判斷檔案描述符是否被置位。

下面是乙個典型的程式片段:

fd_zero(&readset);

fd_set(fd,&readset);

select(fd+1,&readset,null,null,null);

if(fd_isset(fd,readset)

需要注意的是每次呼叫

select

之前都需要重新設定

fd_set

集合。二、

poll

函式原型 

#include

int poll(struct pollfd * fdarray, unsigned long nfds, int timeout);

返回值說明:

>0

準備好描述字的個數;

=0超時;

= -1

表示出錯。

第乙個引數是乙個

pollfd

結構體陣列,其中包括了你想測試的檔案描述符和事件

, 事件由結構中事件域

events

來確定,呼叫後實際發生的時間將被填寫在結構體的

revents

域。struct pollfd ;

等待事件的掩碼:

pollin

普通或優先順序帶資料可讀

pollrdnorm

普通資料可讀

pollrdband

優先順序帶資料可讀

pollpri

高優先順序資料可讀

pollout

普通或優先順序帶資料可寫

pollwrnorm

普通資料可寫

pollwrband

優先順序帶資料可寫

pollerr

發生錯誤

pollhup

發生掛起

pollval

描述字不是乙個開啟的檔案

第一部分為處理輸入的四個常值,第二部分是處理輸出的三個常值,第三部分是處理錯誤的三個常值。

poll

處理三個級別的資料,普通

normal

,優先順序帶

priority band

,高優先順序

high priority

,這些都是出於流的實現。

第二個引數

nfds

用來指定第乙個引數陣列元素個數。

第三個引數指定

poll

函式在返回前等待多長時間,單位為毫秒。當等待時間為0時,

poll()

函式立即返回,為

-1則使

poll()

一直阻塞直到乙個指定事件發生。

如果沒有事件發生,

revents

會被清空,所以你不必多此一舉。

例子如下:

int poll_two_normal(int fd1,int fd2)

if(((poll_list[0].revents&pollhup) == pollhup) ||

((poll_list[0].revents&pollerr) == pollerr) ||

((poll_list[0].revents&pollnval) == pollnval) ||

((poll_list[1].revents&pollhup) == pollhup) ||

((poll_list[1].revents&pollerr) == pollerr) ||

((poll_list[1].revents&pollnval) == pollnval))

return 0;

if((poll_list[0].revents&pollin) == pollin)

handle(poll_list[0].fd,normal_data);

if((poll_list[0].revents&pollpri) == pollpri)

handle(poll_list[0].fd,hipri_data);

if((poll_list[1].revents&pollin) == pollin)

handle(poll_list[1].fd,normal_data);

if((poll_list[1].revents&pollpri) == pollpri)

handle(poll_list[1].fd,hipri_data);}}

參考文件:

在tomcat web應用程式

在tomcat web應用程式 某人曰 在沒其他工具的情況下不會手動新增web應用的程式設計師是乙個菜鳥 軍哥曰 乙個不會使用好的ide開發工具的程式設計師絕對不是乙個好的程式設計師 開發web應用時,不同型別的檔案有嚴格的存放規則,否則不僅可能會使web應用無法訪問,還會導致web伺服器啟動報錯。...

在應用程式之間傳遞引數

在程式設計中經常會遇到在應用程式間傳遞引數的問題 我總結了兩種方法 一。在用shellexcute啟動另外乙個應用程式的同時將引數傳遞過去.函式shellexcute的原型 hinstance shellexecute hwnd hwnd,父視窗的視窗控制代碼 lpctstr lpoperation...

在應用程式中宿主MEF

在應用程式中宿主mef其實非常簡單,只需要建立乙個組合容器物件 compositioncontainer 的例項,然後將需要組合的部件 parts 和當前宿主程式新增到容器中即可。首先需要新增mef框架的引用,既system.componentmodel.composition.dll,詳細如下 塊...