2014-01-05 62 views
-1

我目前正在學習操作系統,我遇到了一個問題,我不能完全弄明白。系統調用SELECT和TESTMASK

我有這一塊的僞代碼:

for(;;) { 
    mask = teskmask; 
    select(MAXSOCKS,&mask,0,0); 
    if(FD_ISSET(strmfd,&mask)) { 
    clilen=sizeof(cliaddr); 
    newfd=accept(strmfd,(struct sockaddr*)&cliaddr,&clilen); 
    echo(newfd); 
    close(newfd); 
    } 
    if (FD_ISSET(dgrmfd,&mask)) echo (dgrmfd); 
} 

注:考慮MAXSOCKS被定義爲任何(此處無關緊要),strmfd是流式套接字,dgrmfd作爲一個數據報套接字, clilen是客戶端地址的大小, echo(newfd);只是一個函數來回應套接字中的內容。

所以我的問題是:

是什麼/什麼爲testmask和麪具,它是如何在這裏使用?

我知道select會阻塞進程,直到有些套接字可用於讀/寫或異常。

回答

0

得到的回答你的問題最簡單的方法就是閱讀選擇(2)手冊頁,它說:

 
int select(int nfds, 
      fd_set *readfds, fd_set *writefds, fd_set *exceptfds, 
      struct timeval *timeout); 

或相當類似的聲明。所以「testmask」是fd_set。 Select()在輸入時獲取這些掩碼,並在輸出時重新填充它們,除非發出錯誤信號。

在我看到的所有Unix系統中,fd_set是位數組,高達FD_SETSIZE位,並且可能很難將其擴展爲更大的值,因此大於或等於FD_SETSIZE的描述符不能被選擇目標特定的黑客攻擊。所以poll()對於一個大的描述符集合來說是首選。 (如果所有描述符的相對較小的子集在每個週期就緒,那麼作爲kqueue(* BSD,MacOSX),epoll(Linux),/ dev/poll(Solaris)的平臺特定解決方案會更好;對於Linux,對於大約3年前的系統,poll()比基於epoll的方案更有效。)

在Windows系統中,fd_set是具有無限值的套接字數組(整數)的數組,但總計數有限(AFAIR,64 )。

只使用標準的宏來處理fd_set給出了在Unix和Windows之間可移植的代碼。但是這種代碼可能會以不同的方式效率低下。

+0

對,明白了。但是爲什麼我們必須在每個循環中做mask = teskmask? – luispcosta

+0

因爲如果選擇成功,它將重寫所有掩碼。這與poll()分開了'events'和'revents'的另一個區別。 – Netch

+0

那麼在select調用之前可能會有一個testmask的例子呢?通話後面具上會寫些什麼? – luispcosta