2013-07-12 35 views
1

我有20個線程一次只在一個tcp套接字上發送數據並且也接收數據。當我運行我的應用程序時,我沒有看到任何同步問題,但根據我的理解,當兩個線程同時嘗試寫入tcp套接字或者一個線程正在寫入而另一個線程正在讀取而另一個線程正在寫入時,可能會出現一些問題。當兩個線程嘗試寫入同一個tcp套接字時發生同步問題simultaneouslu

如果我的理解是正確的,爲什麼我不面對任何錯誤?

+1

@DavidSchwartz是的,我錯過了問題的第一部分,並回答了關於一個讀者+一個作家的位。誤導評論已刪除。 – simonc

+0

嘗試使用更多線程查看差異,可能會看到一些差異。 – pradipta

+0

+1的建議,我會試一試:) – Ayse

回答

6

有時候,如果在過馬路前你沒有看到兩條路,你仍然可以安全地到達街道的另一邊。這並不意味着每次你做它都會成功。

這是事情,你說「你看不到任何同步問題」,但那只是因爲它碰巧做你想做的事情。翻轉這個 - 你沒有看到任何同步問題的原因是因爲你碰巧想要它做它發生的事情。有人希望它做別的與同樣的代碼看到同步問題。

換句話說,你翻了一個硬幣,可能會出現正面或反面。你以爲它不會得到保證,所以你期待它會出現。它出現了。沒有神祕之處 - 解釋是你期望它發生的事情。如果你期望別的東西,即使它做了同樣的事情,它也不會達到你的預期。

+0

+1,謝謝你的有趣的解釋。 – Ayse

4

首先,每個套接字的發送和接收流是獨立的。一個線程在另一個線程接收時應該沒有問題。

如果多個線程試圖寫入一個套接字,那麼行爲通常是未定義的。實際上,來自其中一個線程的寫入調用將首先進入TCP堆棧狀態機的鎖定,從而阻止任何其他線程進入,寫入其數據,釋放鎖並退出堆棧,從而允許來自其他線程的寫入調用線程繼續。這將允許單個寫入調用被序列化。如果你的協議實現可以用一個寫呼叫發送所有的PDU,那麼很好。如果一個PDU需要多次寫入調用,那麼當多個線程的寫入調用得到交錯時,您的傳出PDU可以被分割。

從多個線程接收來自一個套接字的調用只是...某事。即使堆棧內部同步一次只允許每個套接字一次接收調用,TCP的流式性質也必然會在線程中以僞隨機方式分割接收到的數據。只是不要這樣做,這太瘋狂了。

TCP已經有一個多路複用數據流的機制 - 多個套接字。你應該正確使用它們。

如果您需要在一個套接字上覆用數據流,則應該在TCP上添加數據路由協議,並在一個接收線程中實現此協議。此線程可以保留虛擬連接的列表,以及來自其他線程的服務流/消息請求。

相關問題