<ruby id="bdb3f"></ruby>

    <p id="bdb3f"><cite id="bdb3f"></cite></p>

      <p id="bdb3f"><cite id="bdb3f"><th id="bdb3f"></th></cite></p><p id="bdb3f"></p>
        <p id="bdb3f"><cite id="bdb3f"></cite></p>

          <pre id="bdb3f"></pre>
          <pre id="bdb3f"><del id="bdb3f"><thead id="bdb3f"></thead></del></pre>

          <ruby id="bdb3f"><mark id="bdb3f"></mark></ruby><ruby id="bdb3f"></ruby>
          <pre id="bdb3f"><pre id="bdb3f"><mark id="bdb3f"></mark></pre></pre><output id="bdb3f"></output><p id="bdb3f"></p><p id="bdb3f"></p>

          <pre id="bdb3f"><del id="bdb3f"><progress id="bdb3f"></progress></del></pre>

                <ruby id="bdb3f"></ruby>

                企業??AI智能體構建引擎,智能編排和調試,一鍵部署,支持知識庫和私有化部署方案 廣告
                # 18.3 Socket標記 Socket的行為可能隨著創建時指定的不同而有很大的差異,下表列出了Socket可以指定的標記: | wxSOCKET_NONE | 普通行為(行為和底層的send和recv函數一致). | |:--- |:--- | | wxSOCKET_NOWAIT | 讀和寫操作盡可能快速的返回. | | wxSOCKET_WAITALL | 等待所有的讀寫數據完成操作,除非出現系統錯誤. | | wxSOCKET_BLOCK | 在讀寫數據的時候阻塞GUI界面. | 如果沒有指定任何標記(或者指定了wxSOCKET_NONE標記),I/O操作將在部分數據被讀寫的時候返回,甚至在整個數據還沒有傳輸完的情況下也是這樣.這和使用阻塞方式調用底層的recv或者send函數的效果是一樣的.注意這里所說的阻塞指的是函數被阻止返回,并不意味著圖形用戶界面被凍結. 如果指定了wxSOCKET_NOWAIT標記,I/O將立刻返回.對于讀操作,它將讀取所有當前輸入緩沖區擁有的數據后立刻返回,對于寫操作,它將盡可能多的發送數據以后立刻返回,這取決于當前的輸出緩沖區的大小,這種方式等同于使用非阻塞方式調用底層函數recv或send.同樣, 這里的阻塞也指的是函數返回,而不是用戶界面阻塞. 如果指定了wxSOCKET_WAITALL標記,I/O操作將在所有要求的數據被讀取或者被寫入以后(或者發生系統錯誤)才會返回. 如果需要的話,將以阻塞的方式調度底層系統函數.這相當于使用一個循環重復以阻塞的方式調用recv或者send函數以便傳輸所有的數據.同樣,這里的阻塞也指的是阻塞底層函數而不是GUI.注意ReadMsg和WriteMsg函數將隱式使用這種方式,并且忽略你可能設置的wxSOCKET_NONE或 wxSOCKET_NOWAIT標記. 用來指示wxSOCKET_BLOCK是否在I/O操作的間隙執行Yield操作(譯者注:參見前面關于線程的替代方案中的描述),如果指定了這個標記,socket在底層操作間隙將不會執行Yield動作,反之,如果沒有指定這個標記,那么你要非常小心這可能產生的代碼重入的問題. 總的來說: * wxSOCKET_NONE 總是試圖讀取或者寫入一些數據,但是不關心具體是多少數據. * wxSOCKET_NOWAIT 只關心盡快返回,即使沒有讀取或寫任何數據. * wxSOCKET_WAITALL 將在所有的數據都被寫入或者是讀取的數據達到要求的數目的時候返回. * wxSOCKET_BLOCK 和前面的標記沒有關系,只控制否則在底層操作的間隙執行Yield動作. wxWidget中的阻塞和非阻塞socket 在wxWidgets中的阻塞方式有雙重的含義.在一般的編程中,socket阻塞意味著當前的線程被掛起直至socket操作超時或者數據操作完成.如果是主線程阻塞,則用于界面也相應阻塞. 而在wxWidgets中,有兩種類型的阻塞:socket阻塞和用戶界面阻塞.wxSOCKET_BLOCK標記指示在socket阻塞的時候,是否同時阻塞用戶界面.你也許回問,這怎么可能呢,怎么可能作到阻塞了socket操作而不阻塞用戶界面呢?這主要是因為在socket被阻塞的時候,wxWidgets還可以處理所有的事件,因為socket的底層函數處理的間隙調用了wxYield,這個函數可以處理隊列中所有未處理的事件,包括用戶界面相關的事件.雖然在socket操作未結束之前,代碼一直在socket函數中運轉,但是所有事件還是可以被有序的處理. 對于剛開始使用wxWidgets的人來說,聽上去這是一個很美妙的事情.如果你是第一次使用wxWidgets進行socket編程,你可能會覺得,再也不需要使用任何單獨的線程來處理socket了,你可以將socket設置為wxSOCKET_WAITALL和 wxSOCKET_BLOCK,這樣你可以通過事件機制處理socket數據,而GUI也不會被阻塞,不幸的是,我必須先警告你,這種想法可能是你痛苦的開始. 讓我們來假設一個服務端有兩個活動連接,每一個都設置了wxSOCKET_WAITALL標記.更進一步,我們假設其中一個連接正在以一種很緩慢的速度傳輸一個很大量的數據.Socket 1的讀緩沖區沒有數據了,因此它調用了wxYield,而Socket2還有未處理的事件在隊列里,這時候會發生的事情是:Socket1調用的 wxYield試圖處理Socket2相關的消息,但是因為Socket2的連接很緩慢,它的事件總是結束不了,它也會調用wxYield來避免GUI阻塞,這將導致出現一個名聲不太好的告警消息"wxYield called recursively"(wxYield被遞歸調用),在Socket2的數據傳輸結束之前,應用程序的堆棧將最終被wxYield的遞歸調用給耗盡, 因為遞歸調用使用這些堆棧一直沒有機會釋放,于是人們開始聯系wxWidgets社區,報告發現了一個bug,而實際上,這應該是應用程序自己的問題而不是wxWidgets的問題.應用程序不應該以這種方式來編程,它應該避免這種情形出現,因此,恐怕wxWidgets永遠沒有辦法改正這個問題. 另外一方面,性能也是一個問題,為了不阻止GUI,你的應用程序將不得不浪費CPU的資源.試想一下,用戶界面要立即響應, Socket也要不停的監視是否有數據到來以便產生事件通知應用程序,要讓兩者都得到滿足,wxWidgets所能做的唯一的辦法就是使用循環,不停的以非阻塞的方式去用系統操作select去測試socket,然后再調用wxYield處理GUI事件. 不可用的標記組合 容我再羅嗦一句,不要天真到認為wxWidgets采用了一種神奇的socket處理機制.無論這些Socket的標記在你的第一印象中看起來是多么的誘人,你都不可能同時滿足下面的這些要求: * wxSOCKET_WAITALL * 不阻塞GUI * 少于100%的CPU占用率 * 單線程 你可以指定wxSOCKET_WAITALL并且也不阻塞GUI,但是這將導致100%的CPU占用率.如果你愿意付出阻塞GUI作為代價(指定 wxSOCKET_BLOCK標記),你將可以得到wxSOCKET_WAITALL和0%的CPU占用率. 或者你可以使用多線程來實現同時使用wxSOCKET_WAITALL又不阻塞GUI,并且也不用100%的CPU占用率.你也可以不用 wxSOCKET_WAITALL而使用wxSOCKET_NOWAIT以便可以既不占用100%的CPU又不堵塞GUI.總之一句話,上面的四個條件, 你總可以同時滿足任意三個,但是你不可以四個條件同時滿足. 這些標記是怎樣影響Socket的行為的 wxSOCKET_NONE, wxSOCKET_NOWAIT和wxSOCKET_WAITALL是互斥的,你不可以同時使用他們中間的任何兩個,而wxSOCKET_BLOCK和 wxSOCKET_NOWAIT的組合也是沒有意義的 (如果任何函數都立即返回,怎么可能阻塞GUI呢?), 因此下面五種標記的組合是有意義的: * wxSOCKET_NONE | wxSOCKET_BLOCK: 這種組合和標準的socket調用(recv和send)的行為相同. * wxSOCKET_NOWAIT: 和標準的非阻塞的socket調用行為相同. * wxSOCKET_WAITALL | wxSOCKET_BLOCK: 和普通的阻塞式socket調用的行為相同,只不過recv和send函數將被連續多次調用以便接受或者發送完整的數據. * wxSOCKET_NONE: 和標準的socket調用行為相同,只是由于在完成系統調用之前(比如數據完整接收緩沖區數據之前)調用了wxYield,因此看上去GUI并不會阻塞. * wxSOCKET_WAITALL: 和wxSOCKET_WAITALL | wxSOCKET_BLOCK的行為相同只不過GUI將不被阻塞. 只有最后兩種情況可能出現前面介紹的wxYield函數重入的問題,不過這倆組標記也是在wxWidgets中基于事件的socket編程中最主要的兩種方式(因為他們阻塞了socket但是卻不阻塞GUI).使用這兩組標記的時候要非常小心避免這個問題,雖然它們很強大,很有用,卻也往往是錯誤和麻煩的根源,因為它們太容易被誤解了. 標準socket和wxSocket 使用wxSOCKET_NONE | wxSOCKET_BLOCK或wxSOCKET_NOWAIT的時候和直接使用socket系統調用的效果并沒有不同,唯一的不同是你使用的是 wxWidgets提供的API而不是標準C的API.不過,即使這樣,還是有足夠的理由要使用wxSocket,這些理由包括:wxSocket提供了一個面向對象的接口,隱藏了很多平臺相關的初始化代碼,還提供了一些高級的函數比如WriteMsg和ReadMsg.另外,下一節我們也將看到, wxSocket也使我們可以用流的方式來操作socket.
                  <ruby id="bdb3f"></ruby>

                  <p id="bdb3f"><cite id="bdb3f"></cite></p>

                    <p id="bdb3f"><cite id="bdb3f"><th id="bdb3f"></th></cite></p><p id="bdb3f"></p>
                      <p id="bdb3f"><cite id="bdb3f"></cite></p>

                        <pre id="bdb3f"></pre>
                        <pre id="bdb3f"><del id="bdb3f"><thead id="bdb3f"></thead></del></pre>

                        <ruby id="bdb3f"><mark id="bdb3f"></mark></ruby><ruby id="bdb3f"></ruby>
                        <pre id="bdb3f"><pre id="bdb3f"><mark id="bdb3f"></mark></pre></pre><output id="bdb3f"></output><p id="bdb3f"></p><p id="bdb3f"></p>

                        <pre id="bdb3f"><del id="bdb3f"><progress id="bdb3f"></progress></del></pre>

                              <ruby id="bdb3f"></ruby>

                              哎呀哎呀视频在线观看