• <ins id="pjuwb"></ins>
    <blockquote id="pjuwb"><pre id="pjuwb"></pre></blockquote>
    <noscript id="pjuwb"></noscript>
          <sup id="pjuwb"><pre id="pjuwb"></pre></sup>
            <dd id="pjuwb"></dd>
            <abbr id="pjuwb"></abbr>

            tqsheng

            go.....
            隨筆 - 366, 文章 - 18, 評(píng)論 - 101, 引用 - 0
            數(shù)據(jù)加載中……

            epoll兩種機(jī)制的區(qū)別

            7、epoll兩種機(jī)制的區(qū)別

            說(shuō)明:本文來(lái)自翻譯epoll man文檔。

            1、ETLT這兩種事件分發(fā)機(jī)制的不同。我們假定一個(gè)環(huán)境:

               1. The file descriptor that represents the read side of a pipe ( RFD ) is added inside the epoll device.

               2. Pipe writer writes 2Kb of data on the write side of the pipe.

               3. A call to epoll_wait(2) is done that will return RFD as ready file descriptor.

               4. The pipe reader reads 1Kb of data from RFD.

               5. A call to epoll_wait(2) is done.

            Edge Triggered 工作模式:

                如果我們?cè)诘?步將RFD添加到epoll描述符的時(shí)候使用了EPOLLET標(biāo)志,那么在第5步調(diào)用epoll_wait(2)之后將有可能會(huì)掛起因?yàn)槭S嗟臄?shù)據(jù)還存在于文件的輸入緩沖區(qū)內(nèi)而且數(shù)據(jù)發(fā)出端還在等待一個(gè)針對(duì)已經(jīng)發(fā)出數(shù)據(jù)的反饋信息。只有在監(jiān)視的文件句柄上發(fā)生了某個(gè)事件的時(shí)候ET工作模式才會(huì)匯報(bào)事件Edge Triggered event distribution delivers events。因此在第5步的時(shí)候調(diào)用者可能會(huì)放棄等待仍在存在于文件輸入緩沖區(qū)內(nèi)的剩余數(shù)據(jù)the caller might end up waiting for some data that is already present inside the input buffer.。在上面的例子中會(huì)有一個(gè)事件產(chǎn)生在RFD句柄上,是因?yàn)樵诘?步執(zhí)行了一個(gè)寫(xiě)操作然后事件將會(huì)在第3步被銷毀consumed。因?yàn)榈?步的讀取操作沒(méi)有讀空文件輸入緩沖區(qū)內(nèi)的數(shù)據(jù)因此我們?cè)诘?步調(diào)用 epoll_wait(2)完成后might lock indefinitely。epoll工作在ET模式的時(shí)候必須使用非阻塞套接口以避免由于一個(gè)文件句柄的阻塞讀/阻塞寫(xiě)操作把處理多個(gè)文件描述符的任務(wù)餓死。最好以下面的方式調(diào)用ET模式的epoll接口在后面會(huì)介紹避免可能的缺陷。

                i 基于非阻塞文件句柄

                ii 只有當(dāng)read(2)或者write(2)返回EAGAIN時(shí)才需要掛起等待(意為此時(shí),緩存區(qū)滿或無(wú)數(shù)據(jù))。

            Level Triggered 工作模式

            相反的以LT方式調(diào)用epoll接口的時(shí)候,它就相當(dāng)于一個(gè)速度比較快的poll,and can be used wherever the latter is used since it shares the same semantics。因?yàn)榧词故褂肊T模式的epoll在收到多個(gè)chunk的數(shù)據(jù)的時(shí)候仍然會(huì)產(chǎn)生多個(gè)事件Since even with the Edge Triggered epoll multiple events can be generated up on receival of multiple chunks of data。the caller has the option to specify the EPOLLONESHOT flag, to tell epoll to disable the associated file descriptor after the receival of an event with epoll_wait(2). When the EPOLLONESHOT flag is specified, it is caller responsibility to rearm(重新設(shè)置) the file descriptor using epoll_ctl(2) with EPOLL_CTL_MOD.

            2、While the usage of epoll when employed(使用) like a Level Triggered interface does have the same semantics of poll(2), an Edge Triggered usage requires more clarification(澄清) to avoid stalls(拖延) in the application event loop.

            In this example, listener is a non-blocking socket on which listen(2) has been called. The function do_use_fd() uses the new ready file descriptor until EAGAIN is returned by either read(2) or write(2). An event driven state machine(事件驅(qū)動(dòng)狀態(tài)機(jī)) application should, after having received EAGAIN, record its current state so that at the next call to do_use_fd() it will continue to read(2) or write(2) from where it stopped before.

            示例代碼

            View Code 

            struct epoll_event ev, *events;
            for(;;) {
                nfds 
            = epoll_wait(kdpfd, events, maxevents, -1);
                
            for(n = 0; n < nfds; ++n) {
                    
            if(events[n].data.fd == listener) {
                        client 
            = accept(listener, (struct sockaddr *&local,
                                        
            &addrlen);
                        
            if(client < 0){
                            perror(
            "accept");
                            
            continue;
                        }

                        setnonblocking(client);
                        ev.events 
            = EPOLLIN | EPOLLET;
                        ev.data.fd 
            = client;
                        
            if (epoll_ctl(kdpfd, EPOLL_CTL_ADD, client, &ev) < 0{
                            fprintf(stderr, 
            "epoll set insertion error: fd=%d0,
                                    client);
                            
            return -1;
                        }

                    }

                    
            else
                        do_use_fd(events[n].data.fd);
                }

            }


            When used as an Edge triggered interface, for performance reasons, it is possible to add the file descriptor inside the epoll interface ( EPOLL_CTL_ADD ) once by specifying ( EPOLLIN|EPOLLOUT ). This allows you to avoid continuously switching between EPOLLIN and EPOLLOUT calling epoll_ctl(2) with EPOLL_CTL_MOD.



            水平觸發(fā)(LT, Level Triggered),默認(rèn)方式
            支持阻塞/非阻塞socket。
            內(nèi)核通知某fd就緒,如果不對(duì)fd操作,內(nèi)核會(huì)繼續(xù)通知
            邊緣觸發(fā)(Edge-Triggered)
            只支持非阻塞socket
            內(nèi)核通知某fd就緒,如果不對(duì)fd操作,內(nèi)核不再繼續(xù)通知

            posted on 2012-06-26 14:14 tqsheng 閱讀(149) 評(píng)論(0)  編輯 收藏 引用


            只有注冊(cè)用戶登錄后才能發(fā)表評(píng)論。
            網(wǎng)站導(dǎo)航: 博客園   IT新聞   BlogJava   博問(wèn)   Chat2DB   管理


            久久久久av无码免费网| 精品久久久久香蕉网| 国产精品一久久香蕉产线看| 伊人久久五月天| 日韩欧美亚洲综合久久影院Ds | 久久99精品久久久久久| 久久精品国产色蜜蜜麻豆| 精品久久久久久无码不卡| 香蕉99久久国产综合精品宅男自 | 品成人欧美大片久久国产欧美| 久久久久亚洲av无码专区喷水| 亚洲精品无码久久一线| 99久久国产精品免费一区二区| 久久夜色精品国产亚洲| 要久久爱在线免费观看| 久久精品日日躁夜夜躁欧美| 97久久国产综合精品女不卡 | 精品久久久久久国产三级| 精品久久久久久无码人妻热| 99久久精品免费看国产免费| 国产成人精品久久亚洲高清不卡 | 欧美伊香蕉久久综合类网站| 久久91这里精品国产2020| 色综合久久久久综合99| 久久亚洲AV无码精品色午夜麻豆| 亚洲国产精品无码久久久秋霞2| 欧美熟妇另类久久久久久不卡| 99久久99久久久精品齐齐| 99久久国产综合精品成人影院| 久久久久国产精品三级网| 亚洲国产成人久久综合野外| 国产激情久久久久久熟女老人| 国产人久久人人人人爽| 99久久国产综合精品网成人影院| 亚洲乱码日产精品a级毛片久久| 久久WWW免费人成一看片| 国产精品久久影院| 国产69精品久久久久APP下载 | www.久久精品| 伊人 久久 精品| 亚洲国产精品热久久|