2012-11-01 96 views
1

我正在努力將一些相對簡單的網絡代碼從unix移植到Windows。將多線程網絡服務器從unix移植到windows

簡而言之,有一個管理所有網絡流量的網絡線程。這個單線程大部分時間位於poll()之內(我已經將它轉換爲select(),在Windows上),網絡線程只有在有傳入的網絡數據時纔會喚醒。當客戶端命令到達時,網絡線程將該命令發送給工作線程,以便在後端實際執行工作,然後返回到偵聽更多傳入命令。命令是異步的 - 多個命令可以進入一個套接字,一個接一個接一個。在任何時候,在一個連接上可以有幾十個優秀的命令,所有這些命令都在各種工作線程中工作。

問題是,當工作線程想要發送響應數據時,網絡線程可能在工作線程嘗試發送結果時在poll()內部睡着。網絡線程必須等待poll()超時(或接收另一個數據包),纔會發現有新的出站數據排隊等待發送。

在unix下,我通過在poll()正在監視的描述符中包含一個管道來處理這個問題,並且當一個工作線程有出站數據要發送時,它還將一個字節的數據寫入管道以喚醒網絡線程。但是WinSock似乎只支持在套接字上等待,所以這種方法在Windows中不適用於我。有沒有什麼方法可以讓我在Windows上使用WinSock搶救這個體系結構(這樣我可以在不同平臺之間共享大部分代碼),還是別無選擇,只能編寫自定義網絡服務器實現以用於Windows?

感謝您的諮詢!

回答

1

只能有兩種可能,也不需要你提出瞭解決方案:

1)您已經嘗試發送此連接數據和OS的發送隊列已滿。在這種情況下,不需要中止selectpoll。無論如何,您現在無法在連接上寫信,並且您將盡快自動退出selectpoll

2)您當前未嘗試在此連接上發送數據。在這種情況下,也不需要中止selectpoll。現在只需在工作線程中寫入數據。 (套接字是非阻塞的,對吧?)如果你不寫所有的數據,那隻會是因爲操作系統的發送隊列已滿,在這種情況下通常不會急於寫入(設置合理的超時select呼叫)。

你真的不應該在Windows上使用select。這只是一種可憎的行爲,僅僅是爲了兼容性。如果你打算「真正」支持Windows,那麼你不應該把它變成二流的。網絡I/O確實是平臺特定的。

0

而不是在Windows上使用select,如果您使用IO完成端口和發佈讀取緩衝區,您將獲得明顯更好的結果。在IOCP模型下可以使用PostQueuedCompletionStatus API與服務於IOCP的線程進行通信。

+0

是的,絕對正確。但在這種情況下,我正在使用爲BSD套接字編寫的現有代碼,並試圖儘量減少我爲Windows構建編寫和維護的自定義代碼的數量。如果性能實際上成爲問題並且在這部分代碼中進行性能分析,那麼切換到IOCP是我列表中的第一件事。在此之前,我可能不打擾。 :) –