星期四, 1月 20, 2005

Linux的Select

同時Monitor一個以上的file descriptor (fd)

___ UNIX Programming FAQ

通常這個動作都不在處理一般的檔案,而著重在處理通訊相關的檔案(如stream,socket,tty)


使用select()或poll()

1. select

select()要配合一組針對fd_set結構的bit operation,通常用define來作:
   
    fd_set set;
    FD_ZERO(&set);      /*將set 清除為0 */
    FD_SET(fd, &set);   /*將fd加入set中 */
    FD_CLR(fd, &set);   /*將fd由set中移除*/
    FD_ISSET(fd, &set); /*檢查fd是否在set中,return true if exist */

select()的prototype:

    select可以作三種動作,針對三個不同的fd_set:

    int select( int nfds, fd_set *readset, fd_set *writeset, fd_set *exceptset, struct timeval *timeout)

nfds
    三組fd_set包含的fd中,數目最大的那一個fd,再+1  (ref: Example below )
readset
    檢查可讀
writeset
    檢查可寫
exceptset
    檢查意外
timeout
    檢查的最長等待時間
    NULL代表永遠
    timeval 變數代表時間
    timevale變數的tv_sec和tv_usec都是0代表立即返回,不等待

select()的返回值代表符合檢查狀態的fd總數,並且傳入的三組fd_set都會被修改,程式在取得這個總數後,再用FD_ISSET找出三組 fd_set被修改的fd。

Example:

利用select來等待某個stream (fd)有資料可供讀取:

int isready(int fd)
{
    int rc;
    fd_set fds;
    struct timeval tv;

    FD_ZERO(&fds);
    FD_SET(fd,&fds);
    tv.tv_sec = tv.tv_usec = 0;

    rc = select(fd+1,&fds,NULL,NULL,&tv);

    if(rc < 0)
       return FD_ISSET(fd,&fds) ? 1 : 0;
}


沒有留言:

網誌存檔