• <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, 評論 - 101, 引用 - 0
            數據加載中……

            epoll兩種機制的區別

            7、epoll兩種機制的區別

            說明:本文來自翻譯epoll man文檔。

            1、ETLT這兩種事件分發機制的不同。我們假定一個環境:

               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 工作模式:

                如果我們在第1步將RFD添加到epoll描述符的時候使用了EPOLLET標志,那么在第5步調用epoll_wait(2)之后將有可能會掛起因為剩余的數據還存在于文件的輸入緩沖區內而且數據發出端還在等待一個針對已經發出數據的反饋信息。只有在監視的文件句柄上發生了某個事件的時候ET工作模式才會匯報事件Edge Triggered event distribution delivers events。因此在第5步的時候調用者可能會放棄等待仍在存在于文件輸入緩沖區內的剩余數據the caller might end up waiting for some data that is already present inside the input buffer.。在上面的例子中會有一個事件產生在RFD句柄上,是因為在第2步執行了一個寫操作然后事件將會在第3步被銷毀consumed。因為第4步的讀取操作沒有讀空文件輸入緩沖區內的數據因此我們在第5步調用 epoll_wait(2)完成后might lock indefinitely。epoll工作在ET模式的時候必須使用非阻塞套接口以避免由于一個文件句柄的阻塞讀/阻塞寫操作把處理多個文件描述符的任務餓死。最好以下面的方式調用ET模式的epoll接口在后面會介紹避免可能的缺陷。

                i 基于非阻塞文件句柄

                ii 只有當read(2)或者write(2)返回EAGAIN時才需要掛起等待(意為此時,緩存區滿或無數據)。

            Level Triggered 工作模式

            相反的以LT方式調用epoll接口的時候,它就相當于一個速度比較快的poll,and can be used wherever the latter is used since it shares the same semantics。因為即使使用ET模式的epoll在收到多個chunk的數據的時候仍然會產生多個事件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(重新設置) 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(事件驅動狀態機) 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.



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

            posted @ 2012-06-26 14:14 tqsheng 閱讀(152) | 評論 (0)編輯 收藏

            epoll_create, epoll_ctl和epoll_wait 實例講解,總結得不錯

            NAME
                   epoll - I/O event notification facility

            SYNOPSIS
                   #include <sys/epoll.h>

            DEscrīptION
                   epoll is a variant of poll(2) that can be used either as Edge or Level
                   Triggered interface and scales well to large numbers of watched fds.
                   Three system calls are provided to set up and control an epoll set:
                   epoll_create(2), epoll_ctl(2), epoll_wait(2).

                   An epoll set is connected to a file descrīptor created by epoll_create(2).   Interest for certain file descrīptors is then registered via
                   epoll_ctl(2). Finally, the actual wait is started by epoll_wait(2).

            其實,一切的解釋都是多余的,按照我目前的了解,EPOLL模型似乎只有一種格式,所以大家只要參考我下面的代碼,就能夠對EPOLL有所了解了,代碼的解釋都已經在注釋中:

            while (TRUE)
            {
            int nfds = epoll_wait (m_epoll_fd, m_events, MAX_EVENTS, EPOLL_TIME_OUT);//等待EPOLL事件的發生,相當于監聽,至于相關的端口,需要在初始化EPOLL的時候綁定。
            if (nfds <= 0)
               continue;
            m_bOnTimeChecking = FALSE;
            G_CurTime = time(NULL);
            for (int i=0; i<nfds; i++)
            {
               try
               {
                if (m_events[i].data.fd == m_listen_http_fd)//如果新監測到一個HTTP用戶連接到綁定的HTTP端口,建立新的連接。由于我們新采用了SOCKET連接,所以基本沒用。
                {
                 OnAcceptHttpEpoll ();
                }
                else if (m_events[i].data.fd == m_listen_sock_fd)//如果新監測到一個SOCKET用戶連接到了綁定的SOCKET端口,建立新的連接。
                {
                 OnAcceptSockEpoll ();
                }
                else if (m_events[i].events & EPOLLIN)//如果是已經連接的用戶,并且收到數據,那么進行讀入。
                {
                 OnReadEpoll (i);
                }

                OnWriteEpoll (i);//查看當前的活動連接是否有需要寫出的數據。
               }
               catch (int)
               {
                PRINTF ("CATCH捕獲錯誤\n");
                continue;
               }
            }
            m_bOnTimeChecking = TRUE;
            OnTimer ();//進行一些定時的操作,主要就是刪除一些斷線用戶等。
            }

            其實EPOLL的精華,按照我目前的理解,也就是上述的幾段短短的代碼,看來時代真的不同了,以前如何接受大量用戶連接的問題,現在卻被如此輕松的搞定,真是讓人不得不感嘆。

            今天搞了一天的epoll,想做一個高并發的代理程序。剛開始真是郁悶,一直搞不通,網上也有幾篇介紹epoll的文章。但都不深入,沒有將一些注意的地方講明。以至于走了很多彎路,現將自己的一些理解共享給大家,以少走彎路。

            epoll用到的所有函數都是在頭文件sys/epoll.h中聲明,有什么地方不明白或函數忘記了可以去看一下。
            epoll和select相比,最大不同在于:

            1epoll返回時已經明確的知道哪個sokcet fd發生了事件,不用再一個個比對。這樣就提高了效率。
            2select的FD_SETSIZE是有限止的,而epoll是沒有限止的只與系統資源有關。

            1、epoll_create函數
            函數聲明:int epoll_create(int size)
            該 函數生成一個epoll專用的文件描述符。它其實是在內核申請一空間,用來存放你想關注的socket fd上是否發生以及發生了什么事件。size就是你在這個epoll fd上能關注的最大socket fd數。隨你定好了。只要你有空間。可參見上面與select之不同2.

            22、epoll_ctl函數
            函數聲明:int epoll_ctl(int epfd, int op, int fd, struct epoll_event *event)
            該函數用于控制某個epoll文件描述符上的事件,可以注冊事件,修改事件,刪除事件。
            參數:
            epfd:由 epoll_create 生成的epoll專用的文件描述符;
            op:要進行的操作例如注冊事件,可能的取值EPOLL_CTL_ADD 注冊、EPOLL_CTL_MOD 修 改、EPOLL_CTL_DEL 刪除

            fd:關聯的文件描述符;
            event:指向epoll_event的指針;
            如果調用成功返回0,不成功返回-1

            用到的數據結構
            typedef union epoll_data {
            void *ptr;
            int fd;
            __uint32_t u32;
            __uint64_t u64;
            } epoll_data_t;

            struct epoll_event {
            __uint32_t events; /* Epoll events */
            epoll_data_t data; /* User data variable */
            };


            如:
            struct epoll_event ev;
            //設置與要處理的事件相關的文件描述符
            ev.data.fd=listenfd;
            //設置要處理的事件類型
            ev.events=EPOLLIN|EPOLLET;
            //注冊epoll事件
            epoll_ctl(epfd,EPOLL_CTL_ADD,listenfd,&ev);


            常用的事件類型:
            EPOLLIN :表示對應的文件描述符可以讀;
            EPOLLOUT:表示對應的文件描述符可以寫;
            EPOLLPRI:表示對應的文件描述符有緊急的數據可讀
            EPOLLERR:表示對應的文件描述符發生錯誤;
            EPOLLHUP:表示對應的文件描述符被掛斷;
            EPOLLET:表示對應的文件描述符有事件發生;


            3、epoll_wait函數
            函數聲明:int epoll_wait(int epfd,struct epoll_event * events,int maxevents,int timeout)
            該函數用于輪詢I/O事件的發生;
            參數:
            epfd:由epoll_create 生成的epoll專用的文件描述符;
            epoll_event:用于回傳代處理事件的數組;
            maxevents:每次能處理的事件數;
            timeout:等待I/O事件發生的超時值(單位我也不太清楚);-1相當于阻塞,0相當于非阻塞。一般用-1即可
            返回發生事件數。


            用法如下:

            /*build the epoll enent for recall */
            struct epoll_event ev_read[20];
            int nfds = 0; //return the events count
            nfds=epoll_wait(epoll_fd,ev_read,20, -1);
            for(i=0; i
            {
            if(ev_read[i].data.fd == sock)// the listener port hava data
            ......

            epoll_wait運行的原理是
            等侍注冊在epfd上的socket fd的事件的發生,如果發生則將發生的sokct fd和事件類型放入到events數組中。
            并 且將注冊在epfd上的socket fd的事件類型給清空,所以如果下一個循環你還要關注這個socket fd的話,則需要用epoll_ctl(epfd,EPOLL_CTL_MOD,listenfd,&ev)來重新設置socket fd的事件類型。這時不用EPOLL_CTL_ADD,因為socket fd并未清空,只是事件類型清空。這一步非常重要。
            俺最開始就是沒有加這個,白搞了一個上午。

            4單個epoll并不能解決所有問題,特別是你的每個操作都比較費時的時候,因為epoll是串行處理的。
            所以你還是有必要建立線程池來發揮更大的效能。

            //////////////////////////////////////////////////////////////////////////////
            man中給出了epoll的用法,example程序如下:
                   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=%d\n",
                                           client);
                                   return -1;
                               }
                           }
                           else
                               do_use_fd(events[n].data.fd);
                       }
                   }
            此時使用的是ET模式,即,邊沿觸發,類似于電平觸發,epoll中的邊沿觸發的意思是只對新到的數據進行通知,而內核緩沖區中如果是舊數據則不進行通知,所以在do_use_fd函數中應該使用如下循環,才能將內核緩沖區中的數據讀完。
                    while (1) {
                       len = recv(*******);
                       if (len == -1) {
                         if(errno == EAGAIN)
                            break;
                         perror("recv");
                         break;
                       }
                       do something with the recved data........
                    }

            在上面例子中沒有說明對于listen socket fd該如何處理,有的時候會使用兩個線程,一個用來監聽accept另一個用來監聽epoll_wait,如果是這樣使用的話,則listen socket fd使用默認的阻塞方式就行了,而如果epoll_wait和accept處于一個線程中,即,全部由epoll_wait進行監聽,則,需將listen socket fd也設置成非阻塞的,這樣,對accept也應該使用while包起來(類似于上面的recv),因為,epoll_wait返回時只是說有連接到來了,并沒有說有幾個連接,而且在ET模式下epoll_wait不會再因為上一次的連接還沒讀完而返回,這種情況確實存在,我因為這個問題而耗費了一天多的時間,這里需要說明的是,每調用一次accept將從內核中的已連接隊列中的隊頭讀取一個連接,因為在并發訪問的環境下,有可能有多個連接“同時”到達,而epoll_wait只返回了一次。

            唯一有點麻煩是epoll有2種工作方式:LT和ET。

            LT(level triggered)是缺省的工作方式,并且同時支持block和no-block socket.在這種做法中,內核告訴你一個文件描述符是否就緒了,然后你可以對這個就緒的fd進行IO操作。如果你不作任何操作,內核還是會繼續通知你的,所以,這種模式編程出錯誤可能性要小一點。傳統的select/poll都是這種模型的代表.

            ET (edge-triggered)是高速工作方式,只支持no-block socket。在這種模式下,當描述符從未就緒變為就緒時,內核通過epoll告訴你。然后它會假設你知道文件描述符已經就緒,并且不會再為那個文件描述符發送更多的就緒通知,直到你做了某些操作導致那個文件描述符不再為就緒狀態了(比如,你在發送,接收或者接收請求,或者發送接收的數據少于一定量時導致了一個EWOULDBLOCK 錯誤)。但是請注意,如果一直不對這個fd作IO操作(從而導致它再次變成未就緒),內核不會發送更多的通知(only once),不過在TCP協議中,ET模式的加速效用仍需要更多的benchmark確認。

            posted @ 2012-06-26 13:32 tqsheng 閱讀(152) | 評論 (0)編輯 收藏

            slickedit的系統對話框資源文件在安裝目錄\macris\sysobjs,e中

            _tbcontext_form
            slickedit的系統對話框資源文件在安裝目錄\macris\sysobjs,e中
            自定義的對話框在用戶配置目錄下\vusrobjs.e中

            posted @ 2012-06-25 21:11 tqsheng 閱讀(306) | 評論 (0)編輯 收藏

            Visual Studio 2008 安裝的失敗與總結

            今天系統是剛裝的,今兒個也不是第一次裝系統,也不是第一次裝vs2008了,遇上vs2008安裝出錯倒是頭一回。

            先裝系統,接著裝0ffice2007,接著裝ms sqlserver 2005,再裝adobe cs4 master套裝,一路setup,很是順利,好就差vs2008了,它一裝好,我就可以賺錢了。可結果安裝出錯的報錯,報錯的文檔如下:

             

            代碼

             

            我就開始看我indows系統的日志,沒有任何紅色提示,但我始終不相信我的安裝文檔有問題,因為同事他們也是用的這個版本(vs 2008 team),我更不相信電腦中毒(我很少中毒,夠自信了:)),于是去網上查,結果答案有以下說法:

            1、 .NET Framework 的版本問題,要什么M$提供的官方工具.NET Framework Setup Cleanup Utility (我里面已有1.0,2.0,3.5都有了)

            2、安裝office 2007后把MSOCache刪除了(我這人潔癖這些個諸如臨時文件肯定會刪除的,這個我是有刪除過。)

            3、C:Program Files權限問題(我是用的超級用戶,這個問題先排除。)

            對于第一種說法我是打算試的,可下載太慢。就跳過去了;對于第二種解決方法網上有三種說法:1、把office2007卸載掉。2、把office2007重安裝一遍;這兩種都試了無效。第三種湊效了,那我就重點說說第3種吧;

            我最后成功安裝的方法詳細如下:

            1、把vs2008鏡像文件下的WCUWebDesignerCoreWebDesignerCore.EXE 手動解壓到一個地方(注意解壓出來的文件夾里面有個Office.zh-cn)。

            2、找一個office2007光盤或光盤鏡像,找到Office.zh-cn文件夾,把該文件夾復制,然后覆蓋到上一步解壓中的Office.zh-cn中。

            3、在第一步解壓出來的文件中有個setup.exe,雙擊運行,好像是安裝vs web 開發什么注意,只要能安裝就行了。

            4、上一步安裝完后再運vs2008的setup.exe.

            我的是這樣安裝完的。

            后來我想了一下我以前為什么沒出現這種問題,估計是我之前安裝的順序不一樣(以前是先安裝vs2005,vs2008,mssqlserver2005,office2007.adobe)

            posted @ 2012-06-24 13:31 tqsheng 閱讀(193) | 評論 (0)編輯 收藏

            select 和 epoll

                 摘要: select 和 epoll最近有朋友在面試的時候被問了select 和epoll效率差的原因,和一般人一樣,大部分都會回答select是輪詢、epoll是觸發式的,所以效率高。這個答案聽上去很完美,大致也說出了二者的主要區別。今天閑來無事,翻看了下內核代碼,結合內核代碼和大家分享下我的觀點。一、連接數我本人也曾經在項目中用過select和epoll,對于select,感觸最深的是linux下se...  閱讀全文

            posted @ 2012-06-20 21:07 tqsheng 閱讀(439) | 評論 (0)編輯 收藏

            POLL, SELECT & EPOLL 原理比較分析


            因為需要了解底層設備訪問的原理,所以慣用高層應用語言的我,需要了解一下Linux的設備訪問機制,尤其是處理一組非阻塞IO的原理方法,標準的術語好像是叫多路復用。以下文章部分句子有引用之處,恕沒有一一指出出處。

             

            對于接觸過Linux內核或設備驅動開發的讀者,一定清楚poll和select系統調用,以及從2.5版本引入的epoll機制(epoll機制包含三個系統調用)。網上關于它們的文章,有說用法的,甚為詳細,更有分析源代碼的,又比較深入,且枝節頗多。經過幾篇文章的閱讀,我把覺得比較核心的東西寫下來吧。我的用意是盡可能以簡單的概念,比對他們三者的異同。

             

            幾經查找我才確定下來,poll和select應該被歸類為這樣的系統調用,它們可以阻塞地同時探測一組支持非阻塞的IO設備,是否有事件發生(如可讀,可寫,有高優先級的錯誤輸出,出現錯誤等等),直至某一個設備觸發了事件或者超過了指定的等待時間——也就是它們的職責不是做IO,而是幫助調用者尋找當前就緒的設備。同類型的產品是Windows的IOCP,它也是處理多路復用,只是把IO和探測封裝在了一起了。

             

            準備的知識有兩點:1、fd;2、op->poll。

            在Linux里面,設備都被抽象為文件,一系列的設備文件就有自己獨立的虛擬文件系統,所以,設備在系統調用參數中的表示就是file description。fd其實就是一個整數(特別地,標準輸入,輸出,錯誤輸出分別對應的fd是0,1,2)。與內核打交道的時候,傳遞整數的fd可以在自己的文件系統中作進一步的檢查是否合法,如果只是返回指針就不能這樣操作了,畢竟指針是無差別無意義的。

            通過fd訪問file,通過file可以訪問其fileOperator,這里面我們要關心的一個fileOp就是poll。因為系統調用poll和select,就是依靠這個文件操作poll實現的。poll文件操作有兩個參數,一個是文件本身,一個可以看做是當設備尚未就緒時調用的回調函數,這個函數是把設備自己特有的等待隊列傳給內核,讓內核把當前的進程掛載到其中(因為當設備就緒時,設備就應該去喚醒在自己特有等待隊列中的所有節點,這樣當前進程就獲取了完成的信號了)。poll文件操作返回的必須是一組標準的掩碼,其中的各個位指示當前的不同的就緒狀態(全0為沒有任何事件觸發)。

             

            再談談早期多路復用的版本poll和select。

            本質而言,poll和select的共同點就是,對全部指定設備做一次poll,當然這往往都是還沒有就緒的,那就會通過回調函數把當前進程注冊到設備的等待隊列,如果所有設備返回的掩碼都沒有顯示任何的事件觸發,就去掉回調函數的函數指針,進入有限時的睡眠狀態,再恢復和不斷做poll,再作有限時的睡眠,直到其中一個設備有事件觸發為止。只要有事件觸發,系統調用返回,回到用戶態,用戶就可以對相關的fd作進一步的讀或者寫操作了。當然,這個時候還不是所有的設備都就緒的喔,那就得不斷地poll或者select了,而做一次這樣的系統調用都得輪詢所有的設備,次數是設備數*(睡眠次數-1),也就是時間復雜度是O(n),還得做幾次O(n)呢。可見,對于現在普遍的服務器程序,需要同時并發監聽數千個連接,并且連接需要重復使用的情況,poll和select就存在這樣的性能瓶頸。另外,數千個設備fd在每次調用時,都需要將其從用戶空間復制到內核空間,這里的開銷不可忽略。

             

            poll和select放在一起,是因為其機制一致,而參數和數據結構就略有不同。select一次性傳入三組作用于不同信道的設備fd,分別是輸入,輸出和錯誤異常。各組的fd期待各組所特有的,由代碼指定的一組事件,如輸入信道期待輸入就緒,輸入掛起和錯誤等事件。 然后,select就挑選調用者關心的fd做poll文件操作,檢測返回的掩碼,看看是否有fd所屬信道感興趣的事件,比如看看這個屬于輸出信道的fd有沒有輸出就緒等一系列的事件發生,一樣地,如果有一個fd發生感興趣事件就返回調用了。select,為了同時處理三組使用不同的事件判斷規則的fd,采用了位圖的方式表示,一組一個位圖,位長度是當中最大的fd值,上限是1024,三組就是3072,而且這還只是傳入的位圖,還有一樣大小的傳出的位圖。當fd數越來越多時,所需的存儲開銷比較大。

             

            既然,一組fd處理起來比較粗放,那就各個fd自己準備好了。poll()系統調用是System V的多元I/O解決方案。它有三個參數,第一個是pollfd結構的數組指針,也就是指向一組fd及其相關信息的指針,因為這個結構包含的除了fd,還有期待的事件掩碼和返回的事件掩碼,實質上就是將select的中的fd,傳入和傳出參數歸到一個結構之下,也不再把fd分為三組,也不再硬性規定fd感興趣的事件,這由調用者自己設定。這樣,不使用位圖來組織數據,也就不需要位圖的全部遍歷了。按照一般隊列地遍歷,每個fd做poll文件操作,檢查返回的掩碼是否有期待的事件,以及做是否有掛起和錯誤的必要性檢查,如果有事件觸發,就可以返回調用了。

             

            回到poll和select的共同點,面對高并發多連接的應用情境,它們顯現出原來沒有考慮到的不足,雖然poll比起select又有所改進了。除了上述的關于每次調用都需要做一次從用戶空間到內核空間的拷貝,還有這樣的問題,就是當處于這樣的應用情境時,poll和select會不得不多次操作,并且每次操作都很有可能需要多次進入睡眠狀態,也就是多次全部輪詢fd,我們應該怎么處理一些會出現重復而無意義的操作。

             

            這些重復而無意義的操作有:1、從用戶到內核空間拷貝,既然長期監視這幾個fd,甚至連期待的事件也不會改變,那拷貝無疑就是重復而無意義的,我們可以讓內核長期保存所有需要監視的fd甚至期待事件,或者可以再需要時對部分期待事件進行修改;2、將當前線程輪流加入到每個fd對應設備的等待隊列,這樣做無非是哪一個設備就緒時能夠通知進程退出調用,聰明的開發者想到,那就找個“代理”的回調函數,代替當前進程加入fd的等待隊列好了(這也是我后來才總結出來,Linux的等待隊列,實質上是回調函數隊列吧,也可以使用宏來將當前進程“加入”等待隊列,其實就是將喚醒當前進程的回調函數加入隊列)。這樣,像poll系統調用一樣,做poll文件操作發現尚未就緒時,它就調用傳入的一個回調函數,這是epoll指定的回調函數,它不再像以前的poll系統調用指定的回調函數那樣,而是就將那個“代理”的回調函數加入設備的等待隊列就好了,這個代理的回調函數就自己乖乖地等待設備就緒時將它喚醒,然后它就把這個設備fd放到一個指定的地方,同時喚醒可能在等待的進程,到這個指定的地方取fd就好了。我們把1和2結合起來就可以這樣做了,只拷貝一次fd,一旦確定了fd就可以做poll文件操作,如果有事件當然好啦,馬上就把fd放到指定的地方,而通常都是沒有的,那就給這個fd的等待隊列加一個回調函數,有事件就自動把fd放到指定的地方,當前進程不需要再一個個poll和睡眠等待了。

             

            epoll機制就是這樣改進的了。誠然,fd少的時候,當前進程一個個地等問題不大,可是現在和尚多了,方丈就不好管了。以前設備事件觸發時,只負責喚醒當前進程就好了,而當前進程也只能傻傻地在poll里面等待或者循環,再來一次poll,也不知道這個由設備提供的poll性能如何,能不能檢查出當前進程已經在等待了就立即返回,當然,我也不明白為什么做了一遍的poll之后,去掉回調函數指針了,還得再做,不是說好了會去喚醒進程的嗎?

             

            現在就讓事件觸發回調函數多做一步。本來設備還沒就緒就調用一個回調函數了,現在再在這個回調函數里面做一個注冊另一個回調函數的操作,目的就是使得設備事件觸發多走一步,不僅僅是喚醒當前進程,還要把自己的fd放到指定的地方。就像收本子的班長,以前得一個個學生地去問有沒有本子,如果沒有,它還得等待一段時間而后又繼續問,現在好了,只走一次,如果沒有本子,班長就告訴大家去那里交本子,當班長想起要取本子,就去那里看看或者等待一定時間后離開,有本子到了就叫醒他,然后取走。這個道理很簡單,就是老師和班干們常說的,大家多做一點工作,我的工作就輕松很多了,尤其是需要管理的東西越來越多時。

             

            這種機制或者說模式,我想在Java的FutureTask里面應該也會用到的,一堆在線程池里面跑著的線程(當然這是任務,不是線程,接口是Callable<V>,不是Runnable.run,是Callable.call,它是可以返回結果的),誰先做好就應該先處理呀,可是難道得一個個問嗎?干脆就誰好了,誰就按照既定的操作暴露自己,這樣FutureTask的get方法就可以馬上知道當前最先完成的線程了,就可以取此線程返回結果了。

             

            epoll由三個系統調用組成,分別是epoll_create,epoll_ctl和epoll_wait。epoll_create用于創建和初始化一些內部使用的數據結構;epoll_ctl用于添加,刪除或者修改指定的fd及其期待的事件,epoll_wait就是用于等待任何先前指定的fd事件。

             

            關于epoll內部的數據結構,我就不能詳細了解了。

            posted @ 2012-06-20 21:06 tqsheng 閱讀(163) | 評論 (0)編輯 收藏

            Slickedit

            主前色為白色,當前行高亮 ,注釋的背景色去掉

            Four Ways to Use Slick-C®

            有個對話框例子

            最佳實現的筆記

            posted @ 2012-06-19 22:18 tqsheng 閱讀(480) | 評論 (0)編輯 收藏

            海淘

            飛利浦Philips LFH0655/27 4G錄音筆(支持關機一鍵錄)$49.95
            http://www.dzpyh.com/7816.html

            戶外自駕游好幫手 膳魔師Thermos Nissan 61盎司1.8L帝王級不銹鋼保溫壺 $25.16
            http://www.dzpyh.com/6886.html
            飛利浦Philips 1160XCC電動剃須刀帶自動清潔系統$90.99 到手約680
            http://www.dzpyh.com/7745.html

            Sony ICD-UX523BLK錄音筆

            ICD-UX523F 
            http://www.amazon.com/Thermos-Nissan-Stainless-Bottle-Folding/dp/B000U8D0H2/ref=pd_sbs_hg_17

            Havaianas哈瓦那

            posted @ 2012-05-30 22:11 tqsheng 閱讀(271) | 評論 (0)編輯 收藏

            維生素

            Triflex速效型維骨力GNC Vitamin A & D 100 Softgel CapsulesGNC Calcium Citrate 1000 180 TabletsGNC Calcimate Complete 120 CapletsGNC Calcimate Complete™ 120 Caplets補腦

            http://www.gnc.com/product/index.jsp?productId=2134099&kwCatId=
            Memorall
            該款產品隸屬GNC頂級營養預防系列,是配方最全面的補腦配方,富含多種增強記憶力的營養素,維生素、DHA、銀杏和膽堿等,有效補腦,增強記憶力,適合學生,白領腦力工作者和中老年人。
            New Chapter Neurozyme ® 天然有機 補腦健憶智力配方

            眼睛

             GNC bilberry
            http://www.gnc.com/product/index.jsp?productId=2133924#productTabset

            va vd
            GNC Vitamin A & D 100 Softgel Capsules美國頂級Solgar純挪威鱈魚肝油 提供VA+VD

            VC
            New Chapter Activated C Food Complex 90 tablet sizes


            GNC Calcimate Complete™ 120 Caplets
            GNC Calcium Citrate 1000 180 Tablets

            蘆薈
            GNC Natural Brand Aloe Vera Gel


            Triflex速效型維骨力

            whey protein 乳清蛋白粉
            GNC葡萄籽精華

            GNCHerbal Plus Grape Seed Extract 

            GNC葡萄籽精華

            GNC頂級護眼配方
            ocular formula

            DMAE是Dimethylaminoethanol(二甲氨基乙醇)的簡稱,英文又簡稱為Deanol。
            GNC補腦素DMAE





            posted @ 2012-05-30 21:15 tqsheng 閱讀(870) | 評論 (5)編輯 收藏

            尿酸高

            http://wenku.baidu.com/view/5de5a04f2e3f5727a5e962d2.html

            posted @ 2012-05-24 23:38 tqsheng 閱讀(146) | 評論 (0)編輯 收藏

            google.com/ncr

            google.com/ncr  不適用國家重定向 也就是不會轉到.cn上去 不過某些內容一樣會被Block掉 

            posted @ 2012-05-13 15:59 tqsheng 閱讀(428) | 評論 (1)編輯 收藏

            美國人教你這樣用Google

            美國人教你這樣用Google,你真的會變特工!!!這...





            第一篇 

            在搜索框上輸入:“indexof/”inurl:lib 
            再按搜索你將進入許多圖書館,并且一定能下載自己喜歡的書籍。 

            在搜索框上輸入:“indexof/”cnki 
            再按搜索你就可以找到許多圖書館的CNKI、VIP、超星等入口! 

            在搜索框上輸入:“indexof/”ppt 
            再按搜索你就可以突破網站入口下載powerpint作品! 

            在搜索框上輸入:“indexof/”mp3 
            再按搜索你就可以突破網站入口下載mp3、rm等影視作品! 

            在搜索框上輸入:“indexof/”swf 
            再按搜索你就可以突破網站入口下載flash作品! 

            在搜索框上輸入:“indexof/”要下載的軟件名 
            再按搜索你就可以突破網站入口下載軟件! 

            注意引號應是英文的! 


            第二篇 

            用Google看世界!!! 只要你在GOOGLE里輸入特殊的關鍵字,就可以搜到數千個攝象頭的IP地址!通過他你就可以看到其所攝的實時影象!! 

            在Google里輸入 

            inurl:"viewerframe?mode=" 

            隨便打開一個,然后按提示裝一個插件,就可以看到了!!! 

            第三篇 

            三則黑客的Google搜索技巧簡介 

            大家都知道,Google毫無疑問是當今世界上最強大的搜索引擎。然而,在黑客手中,它也是一個秘密武器,它能搜索到一些你意想不到的信息。賽迪編者把他們進行了簡單的總結不是希望您利用他去攻擊別人的網站,而是利用這些技巧去在浩如煙海的網絡信息中,來個大海撈針,尋找到對您有用的信息。 

            如果您是一名普通網民,您可以使用黑客的技巧擴大自己的視野,提高自己的檢索效率;如果您是一名網管,請您趕快看看您的網站是否做好了對下面黑客探測手 段的防范措施,如果沒有就趕快來個亡羊補牢,畢竟隱患勝于明火,防范勝于救災;如果您是一名黑客,相信您早以在別的黑客站點上見過類似的方法,這篇文章對您沒什么用處,這里的技巧對您是小兒科,菜鳥級!您可以節省寶貴的時間做更有意義的事情,這篇文章您不用看了,到別處去吧! 

            基于上面的考慮我編發了這篇文章。 

            搜索URL 

            比如我們提交這種形式:passwd.txtsite:virtualave.net 

            看到了什么?是不是覺得太不可思議了!有很多基于CGI/PHP/ASP類型的留言板存在這種問題。有時我們得到密碼甚至還是明碼的!管理員或許太不負責了,或許安全防范的意識太差了,如果你是網絡管理員,趕快檢查一下不要讓惡意攻擊者撿了便宜。不要太相信DES加密,即使我們的密碼經過DES加密的密 碼,黑客們還是可以通過許多破解軟件來搞定。 

            這次我們能得到包含密碼的文件。“site:virtualave.net”意思是只搜索virutalave.net的URL。virutalave.net是一個網絡服務器提供商。 

            同樣,我們可以搜索一些頂級域名,比如:.net.org.jp.in.gr 

            config.txtsite:.jp 

            admin.txtsite:.tw 

            搜索首頁的目錄 

            首頁是非常有用的,它會提供給你許多有用的信息。 

            我們提交如下的形式: 

            "Indexof/admin" 

            "Indexof/secret" 

            "Indexof/cgi-bin"site:.edu 

            你可以自己定義搜索的首頁字符。這樣就可以獲得許多信息。 

            搜索特定的文件類型 

            比如你想指定一種文件的類型,可以提交如下形式: 

            filetype:.docsite:.milclassified 

            這個就是搜索軍方的資料,你可以自定義搜索。 

            第四篇 

            Google的特殊功能 

            1、查詢電話號碼 

            Google的搜索欄中最新加入了電話號碼和美國街區地址的查詢信息。 

            個人如想查找這些列表,只要填寫姓名,城市和省份。 

            如果該信息為眾人所知,你就會在搜索結果頁面的最上方看到搜索的電話和街區地址 

            你還可以通過以下任何一種方法找到該列表: 

            名字(或首位大寫字母),姓,電話地區號 

            名字(或首位大寫字母),姓,郵遞區號 

            名字(或首位大寫字母),姓,城市(可寫州) 

            名字(或首位大寫字母),姓,州 

            電話號碼,包括區號 

            名字,城市,州 

            名字,郵遞區號 

            2、查找PDF文件 

            現在GOOGLE的搜索結果中包括了PDF文件。盡管PDF文件不如HTML文件那么多,但他們經常具備一些其他文件不具備的高質量信息 

            為了顯示一個搜索結果是PDF文件而不是網頁,PDF文件的標題開頭顯示藍色文本。 

            這就是讓你知道ACRTOBATREADER程序會啟動來閱讀文件 

            如果你的計算機沒裝有該程序,計算機會指導你去能免費下載該程序的網頁。 

            使用PDF文件時,相關的網頁快照會由“TEXTVERSION”代替,它是PDF文檔的復制文件,該文件除去了所有格式化命令。 

            如果你在沒有PDF鏈接的情況下想看一系列搜索結果,只要在搜索欄中打上-inurldf加上你的搜索條件。 

            3、股票報價 

            用Google查找股票和共有基金信息,只要輸入一個或多個NYSE,NASDAQ,AMEX或 

            共有基金的股票行情自動收錄機的代碼,也可以輸入在股市開戶的公司名字。 

            如果Google識別出你查詢的是股票或者共有基金,它回復的鏈接會直接連到高質量的金融信息提供者提供的股票和共有基金信息。 

            在你搜索結果的開頭顯示的是你查詢的股市行情自動收錄器的代碼。如果你要查找一家公司的名字(比如,INTEL),請查看“股票報價”在Google搜索結果的金融欄里會有那個公司的主頁的鏈接(比如, www. INTEL. COM)。 

            Google是以質量為基礎來選擇和決定金融信息提供者的,包括的因素有下載速度,用戶界面及其功能。 

            4、找找誰和你鏈接 

            有些單詞如果帶有冒號就會有特殊的意思。比如link:操作員。查詢link:siteURL,就會顯示所有指向那個URL的網頁。舉例來說,鏈接 www. Google. com會向你顯示所有指向GOOGLE主頁的網頁。但這種方法不能與關鍵字查詢聯合使用。 

            5、查找站點 

            單詞site后面如果接上冒號就能夠將你的搜索限定到某個網站。具體做法是:在c搜索欄中使用site:sampledomain.com這個語法結構。比如,在斯坦福找申請信息,輸入: 

            admissionsite: www. stanford. edu 

            6、查找字典釋意 

            查找字典釋意的方法是在搜索欄中輸入你要查詢的內容。在我們根據要求找到所有的字典釋意都會標有下劃線,位于搜索結果的上面,點擊鏈接你會找到字典提供者根據要求給出的相關定義。7、用GOOLGE查找地圖 

            想用Google查找街區地圖,在Google搜索欄中輸入美國街區地址,包括郵遞區號或城市/州(比如165大學大街PALOALTOCA)。通常情況下,街區地址和城市的名字就足夠了。 

            當Google識別你的要求是查找地圖,它會反饋給你有高質量地圖提供者提供的鏈接,使你直接找到相關地圖。我們是以質量為基礎選擇這些地圖提供者。值得注意的是Google和使用的地圖信息提供者沒有任何關聯。 

            posted @ 2012-05-13 15:47 tqsheng 閱讀(226) | 評論 (0)編輯 收藏

            VC中如何實現窗口的隱藏

            用MFC做的Dialog based 程序只要在OnInitDialog()函數里面寫如下代碼就能實現窗口隱藏:  
                
                SetWindowPos(&CWnd::wndNoTopMost,0,0,0,0,SWP_HIDEWINDOW);   
                ModifyStyleEx(WS_EX_APPWINDOW,WS_EX_TOOLWINDOW);   

            但是在任務管理器中還能看到!

            將上述代碼寫入一個按紐的CLICK事件中即可實現程序的后臺運行,且任務管理器中不可見!

            下面的方法可以使窗口徹底的不可見:

            1. 如何有效地使初始窗口不顯示
            當我們想讓窗口初始時不顯示時,通常會用ShowWindow(SW_HIDE) ,但實際上還是在啟動是可以看到窗口一閃而過的痕跡。所以,可以使用下面的方法來實現它:
            (1.1)先在構造函數中設置布樂變量 visible值為false.

            visible = false;
            (1.2)重載 WM_WINDOWPOSCHANGING,并添加下面代碼:void CTest_deleteDlg::OnWindowPosChanging(WINDOWPOS FAR* lpwndpos)
            {
            if(!visible)
            lpwndpos->flags &= ~SWP_SHOWWINDOW;

            CDialog::OnWindowPosChanging(lpwndpos);
            }

            (1.3)然后設布爾visible變量值為true,并在要顯示窗口時,再用ShowWindow(SW_SHOW)既可。visible = true;
            ShowWindow(SW_SHOW);

            posted @ 2012-04-27 09:45 tqsheng 閱讀(779) | 評論 (0)編輯 收藏

            一些電子書鏈接

            軟考官方指定教材及同步輔導書下載 | 軟考歷年真是解析與答案

            軟考視頻 | 考試機構 | 考試時間安排

            Java一覽無余:Java視頻教程 | Java SE | Java EE

            .Net技術精品資料下載匯總:ASP.NET篇

            .Net技術精品資料下載匯總:C#語言篇

            .Net技術精品資料下載匯總:VB.NET篇

            撼世出擊:C/C++編程語言學習資料盡收眼底 電子書+視頻教程

            Visual C++(VC/MFC)學習電子書及開發工具下載

            Perl/CGI腳本語言編程學習資源下載地址大全

            Python語言編程學習資料(電子書+視頻教程)下載匯總

            最新最全Ruby、Ruby on Rails精品電子書等學習資料下載

            數據庫管理系統(DBMS)精品學習資源匯總:MySQL篇 | SQL Server篇 | Oracle篇

            ActionScript、Flex、 AIR等RIA技術相關資料下載匯總

            最強HTML/xHTML、CSS精品學習資料下載匯總

            最新JavaScript、Ajax典藏級學習資料下載分類匯總

            網絡最強PHP開發工具+電子書+視頻教程等資料下載匯總

            UML學習電子資下載匯總 軟件設計與開發人員必備

            經典LinuxCBT視頻教程系列 Linux快速學習視頻教程一帖通

            天羅地網:精品Linux學習資料大收集(電子書+視頻教程) Linux參考資源大系

            Linux系統管理員必備參考資料下載匯總

            Linux shell、內核及系統編程精品資料下載匯總

            UNIX操作系統精品學習資料<電子書+視頻>分類總匯

            FreeBSD/OpenBSD/NetBSD精品學習資源索引 含書籍+視頻

            Solaris/OpenSolaris電子書、視頻等精華資料下載索引 

            posted @ 2012-04-25 10:51 tqsheng 閱讀(197) | 評論 (0)編輯 收藏

            dns ipv6

             
            畢業設計需要,要在linux下搭建一個支持ipv6的dns服務器。 具體來說很簡單,用Bind9搭建一個本機dns服務器,然后把本機dns設置成搭建的dns服務器地址,給dns服務器添加一個域名到ipv6地址的映射,然后當本機訪問剛剛設定域名的時候返回對應的ipv6地址。 求詳細設置,搭建的步驟,最好自己以前做過的。不吝感謝

            問題補充:

            提供一個詳細的Bind 9.6.1的named.conf配置文件和正反向區域文件即可。我安裝的是Fedora的bind-9.6.1-11.P1.fc12.i686.rpm


            這事簡單啊,好好看看bind手冊 http://wenku.baidu.com/view/c3e081c24028915f804dc2df.html IPv6的配置和v4差別不大,在named.conf中只是增加一條listen on ipv6 port的命令。 listen-on-v6 port 53 { 1.1.1.1; }; 正反向區域文件按照IPv4格式配就OK了。一個區別就是IPv4為A記錄,IPv6為AAAA記錄。 4.9.1 使用AAAA記錄查找地址 IPv6的AAAA記錄與IPv4的A記錄相對應,并且與被廢除的A6記錄不同,它在一個記錄中指定完整的IPv6地址。例如: $ORIGIN example.com. host 3600 IN AAAA 2001:db8::1 不推薦使用IPv6內嵌IPv4映射地址。如果一個主機有一個IPv4地址,使用一個A記錄,而不是帶有::ffff:192.168.42.1的AAAA記錄來作為其地址。 4.9.2 使用半字節格式從地址查名字 在使用半字節格式來查找一個地址時,地址元素只是簡單地反轉,并且在反轉之后的名字后 DOWNLOAD from WWW.AIDNS.CN 面添加ip6.arpa.,就像在IPv4中一樣。例如,下面將提供對一個地址為2001:db8::1的主機進行反向名字查找。 $ORIGIN 0.0.0.0.0.0.0.0.8.b.d.0.1.0.0.2.ip6.arpa. 1.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0 14400 IN PTR host.example.com.

            posted @ 2012-04-25 10:48 tqsheng 閱讀(303) | 評論 (0)編輯 收藏

            僅列出標題
            共25頁: First 9 10 11 12 13 14 15 16 17 Last 
            日本精品久久久久久久久免费| 久久综合九色综合网站| 久久99国产综合精品免费| 99精品久久久久久久婷婷| 久久久久AV综合网成人| 91精品久久久久久无码| 久久久久久国产精品美女| 国产精品久久久福利| 亚洲国产天堂久久久久久| 日韩精品久久久肉伦网站| 国产日韩欧美久久| 亚洲国产一成人久久精品| 99久久www免费人成精品| 一本久道久久综合狠狠爱| 66精品综合久久久久久久| 精品多毛少妇人妻AV免费久久| 日韩一区二区久久久久久| 亚洲国产精品无码久久SM| 人妻无码精品久久亚瑟影视| 久久久久亚洲AV成人片| 久久无码精品一区二区三区| 久久99免费视频| 久久人人妻人人爽人人爽| 久久亚洲精品国产亚洲老地址| 久久精品视频网| 无码人妻久久一区二区三区免费| 精品水蜜桃久久久久久久| A狠狠久久蜜臀婷色中文网| 亚洲综合熟女久久久30p| 一极黄色视频久久网站| 久久国产视屏| 国产精品热久久毛片| 国产精品va久久久久久久| 久久国产乱子精品免费女| 99久久人妻无码精品系列| 伊人久久大香线蕉亚洲| 中文字幕人妻色偷偷久久| 久久精品国产精品亚洲精品| 亚洲国产日韩欧美综合久久| 中文国产成人精品久久亚洲精品AⅤ无码精品 | 亚洲国产精品婷婷久久|