欧美性猛交XXXX免费看蜜桃,成人网18免费韩国,亚洲国产成人精品区综合,欧美日韩一区二区三区高清不卡,亚洲综合一区二区精品久久

打開(kāi)APP
userphoto
未登錄

開(kāi)通VIP,暢享免費電子書(shū)等14項超值服

開(kāi)通VIP
select poll使用
select poll使用
   


2.1. 如何管理多個(gè)連接?
“我想同時(shí)監控一個(gè)以上的文件描述符(fd)/連接(connection)/流(stream),應該怎么辦?” 

使用 select() 或 poll() 函數。 

注 意:select() 在BSD中被引入,而poll()是SysV STREAM流控制的產(chǎn)物。因此,這里就有了平臺移植上的考慮:純粹的BSD系統可 能仍然缺少poll(),而早一些的SVR3系統中可能沒(méi)有select(),盡管在SVR4中將其加入。目前兩者都是POSIX. 1g標準,(譯者 注:因此在Linux上兩者都存在) 

select()和poll()本質(zhì)上來(lái)講做的是同一件事,只是完成的方法不一樣。兩者都通過(guò)檢驗一組文件描述符來(lái)檢測是否有特定的時(shí)間將在上面發(fā)生并在一定的時(shí)間內等待其發(fā)生。 

[重要事項:無(wú)論select()還是poll() 都不對普通文件起很大效用,它們著(zhù)重用于套接口(socket)、管道(pipe)、偽終端(pty)、終端設備(tty)和其他一些字符設備,但是這些操作都是系統相關(guān)(system-dependent)的。] 

2.1.1. 我如何使用select()函數?
select() 函數的接口主要是建立在一種叫'fd_set'類(lèi)型的基礎上。它('fd_set') 是一組文件描述符(fd)的集合。由于fd_set類(lèi)型的長(cháng)度在不同平臺上不同,因此應該用一組標準的宏定義來(lái)處理此類(lèi)變量: 

    fd_set set;
    FD_ZERO(&set);       /* 將 set清零 */
    FD_SET(fd, &set);    /* 將fd加入set */
    FD_CLR(fd, &set);    /* 將 fd從set中清除 */
    FD_ISSET(fd, &set);  /* 如果fd在set中則真 */
      
在 過(guò)去,一個(gè)fd_set通常只能包含少于等于32個(gè)文件描述符,因為fd_set其實(shí)只用了一個(gè)int的比特矢量來(lái)實(shí)現,在大多數情況下,檢查 fd_set能包括任意值的文件描述符是系統的責任,但確定你的fd_set到底能放多少有時(shí)你應該檢查/修改宏FD_SETSIZE的值。*這個(gè)值是系 統相關(guān)的*,同時(shí)檢查你的系統中的select() 的man手冊。有一些系統對多于1024個(gè)文件描述符的支持有問(wèn)題。[譯者注: Linux就是這樣 的系統!你會(huì )發(fā)現sizeof(fd_set)的結果是128(*8 = FD_SETSIZE=1024) 盡管很少你會(huì )遇到這種情況。] 

select 的基本接口十分簡(jiǎn)單: 

    int select(int nfds, fd_set *readset, fd_set *writeset,
               fd_set *exceptset, struct timeval *timeout);
      
其中: 

nfds     
     需要檢查的文件描述符個(gè)數,數值應該比是三組fd_set中最大數
     更大,而不是實(shí)際文件描述符的總數。
readset    
     用來(lái)檢查可讀性的一組文件描述符。
writeset
     用來(lái)檢查可寫(xiě)性的一組文件描述符。
exceptset
     用來(lái)檢查意外狀態(tài)的文件描述符。(注:錯誤并不是意外狀態(tài))
timeout
     NULL 指針代表無(wú)限等待,否則是指向timeval結構的指針,代表最
     長(cháng)等待時(shí)間。(如果其中tv_sec和tv_usec都等于0, 則文件描述符
     的狀態(tài)不被影響,但函數并不掛起)
      
函數將返回響應操作的對應操作文件描述符的總數,且三組數據均在恰當位置被修改,只有響應操作的那一些沒(méi)有修改。接著(zhù)應該用FD_ISSET宏來(lái)查找返回的文件描述符組。 

這里是一個(gè)簡(jiǎn)單的測試單個(gè)文件描述符可讀性的例子: 

     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 -1;
    
         return FD_ISSET(fd,&fds) ? 1 : 0;
     }
      
當然如果我們把NULL指針作為fd_set傳入的話(huà),這就表示我們對這種操作的發(fā)生不感興趣,但select() 還是會(huì )等待直到其發(fā)生或者超過(guò)等待時(shí)間。 

[譯 者注:在Linux中,timeout指的是程序在非sleep狀態(tài)中度過(guò)的時(shí)間,而不是實(shí)際上過(guò)去的時(shí)間,這就會(huì )引起和非Linux平臺移植上的時(shí)間不 等問(wèn)題。移植問(wèn)題還包括在System V風(fēng)格中select()在函數退出前會(huì )把timeout設為未定義的 NULL狀態(tài),而在BSD中則不是這樣, Linux在這點(diǎn)上遵從System V,因此在重復利用timeout指針問(wèn)題上也應該注意。] 

2.1.2. 我如何使用 poll()?
poll ()接受一個(gè)指向結構'struct pollfd'列表的指針,其中包括了你想測試的文件描述符和事件。事件由一個(gè)在結構中事件域的比特掩碼確定。當前 的結構在調用后將被填寫(xiě)并在事件發(fā)生后返回。在SVR4(可能更早的一些版本)中的 "poll.h"文件中包含了用于確定事件的一些宏定義。事件的等待 時(shí)間精確到毫秒 (但令人困惑的是等待時(shí)間的類(lèi)型卻是int),當等待時(shí)間為0時(shí),poll()函數立即返回,-1則使poll()一直掛起直到一個(gè)指定 事件發(fā)生。下面是pollfd的結構。 

     struct pollfd {
         int fd;        /* 文件描述符 */
         short events;  /* 等待的事件 */
         short revents; /* 實(shí)際發(fā)生了的事件 */
     };
      
于select()十分相似,當返回正值時(shí),代表滿(mǎn)足響應事件的文件描述符的個(gè)數,如果返回0則代表在規定事件內沒(méi)有事件發(fā)生。如發(fā)現返回為負則應該立即查看 errno,因為這代表有錯誤發(fā)生。 

如果沒(méi)有事件發(fā)生,revents會(huì )被清空,所以你不必多此一舉。 

這里是一個(gè)例子 

   /* 檢測兩個(gè)文件描述符,分別為一般數據和高優(yōu)先數據。如果事件發(fā)生
      則用相關(guān)描述符和優(yōu)先度調用函數handler(),無(wú)時(shí)間限制等待,直到
      錯誤發(fā)生或描述符掛起。*/
   
   #include <stdlib.h>
   #include <stdio.h>
  
   #include <sys/types.h>
   #include <stropts.h>
   #include <poll.h>
  
   #include <unistd.h>
   #include <errno.h>
   #include <string.h>
  
   #define NORMAL_DATA 1
   #define HIPRI_DATA 2
  
   int poll_two_normal(int fd1,int fd2)
   {
       struct pollfd poll_list[2];
       int retval;
  
       poll_list[0].fd = fd1;
       poll_list[1].fd = fd2;
       poll_list[0].events = POLLIN|POLLPRI;
       poll_list[1].events = POLLIN|POLLPRI;
  
       while(1)
       {
           retval = poll(poll_list,(unsigned long)2,-1);
           /* retval 總是大于0或為-1,因為我們在阻塞中工作 */
  
           if(retval < 0)
           {
               fprintf(stderr,"poll 錯誤: %s\n",strerror(errno));
               return -1;
           }
    
           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);
       }
   }
      
2.1.3. 我是否可以同時(shí)使用SysV IPC和select()/poll()?
*不能。* (除非在A(yíng)IX上,因為它用一個(gè)無(wú)比奇怪的方法來(lái)實(shí)現這種組合) 

一般來(lái)說(shuō),同時(shí)使用select()或poll()和SysV 消息隊列會(huì )帶來(lái)許多麻煩。SysV IPC的對象并不是用文件描述符來(lái)處理的,所以它們不能被傳遞給select()和 poll()。這里有幾種解決方法,其粗暴程度各不相同: 


完全放棄使用 SysV IPC。 :-)

用fork(),然后讓子進(jìn)程來(lái)處理SysV IPC,然后用管道或套接口和父進(jìn)程 說(shuō)話(huà)。父進(jìn)程則使用 select()。 

同上,但讓子進(jìn)程用select(),然后和父親用消息隊列交流。 

安排進(jìn)程發(fā)送消息給你,在發(fā)送消息后再發(fā)送一個(gè)信號。*警告*:要做好 這個(gè)并不簡(jiǎn)單,非常容易寫(xiě)出會(huì )丟失消息或引起死鎖的程序。 

另外還有其他方法。 

poll :

 

luanjian 2006-7-19 01:47
驅動(dòng)中poll_wait()函數的疑問(wèn)

應用程序的 select()系統調用,調用驅動(dòng)中的poll()方法。
不理解的是在下面的poll()方法實(shí)現中,首先調用poll_wait將等待隊列添加到wait結構中,接下來(lái)是個(gè)判斷語(yǔ)句  
if (dev->rp != dev->wp)
                mask |= POLLIN | POLLRDNORM;  /* readable */
只 考慮可讀情況。如果這個(gè)if語(yǔ)句的條件不滿(mǎn)足,那么就不會(huì )返回可讀,也就是返回0。那么在這里怎么實(shí)現阻塞的呢?也就是說(shuō)如果在應用的select()系 統中,指定一個(gè)等待時(shí)間,在這個(gè)等待時(shí)間里如果沒(méi)有描述符可讀,就一直阻塞。那個(gè)這個(gè)等待時(shí)間是怎么和驅動(dòng)中的poll()方法聯(lián)系起來(lái)的呢?如果要修改 這個(gè)poll()方法怎么修改呢?還有在poll()方法中,怎么指定描述符集中的哪一個(gè)是可讀的呢?簡(jiǎn)單的返回POLLIN | POLLRDNORM,是無(wú)法指定是哪一個(gè)描述符可讀的呀?
               
static unsigned int scull_p_poll(struct file *filp, poll_table *wait)
{
        struct scull_pipe *dev = filp->private_data;
        unsigned int mask = 0;

        /*
        * The buffer is circular; it is considered full
        * if "wp" is right behind "rp" and empty if the
        * two are equal.
        */
        down(&dev->sem);
        poll_wait(filp, &dev->inq,  wait);
       // poll_wait(filp, &dev->outq, wait);
        if (dev->rp != dev->wp)
                mask |= POLLIN | POLLRDNORM;  /* readable */
        //if (spacefree(dev))
        //        mask |= POLLOUT | POLLWRNORM;  /* writable */
        up(&dev->sem);
        return mask;
}

siasd 2006-7-19 02:14
在調用驅動(dòng)程序的poll之前,實(shí)現調用VFS相關(guān)的poll接口的(比如sys_poll等),阻塞、等待時(shí)間等的實(shí)現是在那個(gè)里面完成的

luanjian 2006-7-19 02:28
那么驅動(dòng)的這個(gè)poll()方法總是立刻返回的?

siasd 2006-7-19 02:49
對啊

luanjian 2006-7-19 03:07
是立刻返回的,那么如果有一個(gè)描述符集當前不可讀,也就返回0。但等了一段時(shí)間后可讀,那么怎么返回mask |= POLLIN | POLLRDNORM;。我的意思是怎么指示給應用程序可讀的呢?
那么驅動(dòng)的poll()方法的作用是什么呢?

siasd 2006-7-19 03:19
如果當前不可讀,那么在sys_poll->do_poll中當 前進(jìn)程就會(huì )睡眠在等待隊列上,這個(gè)等待隊列是由驅動(dòng)程序提供的(就是poll_wait中傳入的那個(gè))。當可讀的時(shí)候,驅動(dòng)程序可能有一部分代碼運行了 (比如驅動(dòng)的中斷服務(wù)程序),那么在這部分代碼中,就會(huì )喚醒等待隊列上的進(jìn)程,也就是之前睡眠的那個(gè),當那個(gè)進(jìn)程被喚醒后do_poll會(huì )再一次的調用驅 動(dòng)程序的poll函數,這個(gè)時(shí)候應用程序就知道是可讀的了。

不知道有沒(méi)有解釋清楚啊,呵呵

luanjian 2006-7-19 03:24
非常感謝。

snow_insky 2006-7-19 04:30
POOL方法就是用來(lái)支持非阻塞式的訪(fǎng)問(wèn),當然是立即返回,但是它會(huì )把這次請求放入一個(gè)等待隊列中,當某個(gè)條件滿(mǎn)足時(shí),內核會(huì )通知應用程序(應用程序的select函數會(huì )感知),然后就會(huì )接著(zhù)select操作
本站僅提供存儲服務(wù),所有內容均由用戶(hù)發(fā)布,如發(fā)現有害或侵權內容,請點(diǎn)擊舉報。
打開(kāi)APP,閱讀全文并永久保存 查看更多類(lèi)似文章
猜你喜歡
類(lèi)似文章
poll用法舉例
Linux poll實(shí)例
poll函數
C語(yǔ)言:poll函數...........
驅動(dòng)實(shí)現select機制的步驟
【原創(chuàng )】Linux select/poll機制原理分析
更多類(lèi)似文章 >>
生活服務(wù)
分享 收藏 導長(cháng)圖 關(guān)注 下載文章
綁定賬號成功
后續可登錄賬號暢享VIP特權!
如果VIP功能使用有故障,
可點(diǎn)擊這里聯(lián)系客服!

聯(lián)系客服

欧美性猛交XXXX免费看蜜桃,成人网18免费韩国,亚洲国产成人精品区综合,欧美日韩一区二区三区高清不卡,亚洲综合一区二区精品久久