2010-05-03 74 views
1

由於Windows不提供UNIX域套接字,因此我使用本地TCP連接來模擬行爲。現在,POSIX保證,如果有多個線程並行寫入UNIX域套接字,則會自動處理到PIPE_BUF的塊 - 即不會發生交織。本地TCP winsock是否有類似的保證,還是我必須使用臨界區來同步編寫器?Winsocks上的原子性保證?

+0

我以爲Windows提供的郵件插槽與Unix本地插槽一樣。並命名管道。 – 2010-05-03 17:51:20

+0

命名管道的問題是AFAIK無法選擇()它們。 – sustrik 2010-05-03 18:02:56

回答

0

它沒有明確保證。鎖。除非您處於非常緊密的環路中,否則無用的鎖定便宜。如果你真的不想這樣做,使用重疊的I/O。

+0

如何在這裏使用重疊的I/O?如果他有多個線程寫入同一個套接字然後不同的獨立寫入將交錯,除非他鎖定... – 2010-05-03 17:51:01

+0

嗯,實際上,使用本地UDP可能有助於得到的行爲... – sustrik 2010-05-03 18:01:28

+0

但我認爲不能保證UDP數據包得到通過本地網絡堆棧。 – sustrik 2010-05-03 18:02:19

1

如果你有幾個線程寫入同一個套接字,那麼每個寫入調用都是原子的,但是每個寫入調用相對於在不同線程上發生的其他寫入調用是交錯的;

因此,如果你有一個線程1在一個單獨的寫入中寫入A的字符串,並且線程2用一個寫入和一系列的C寫入一系列的B和另一個,那麼你可能會得到ABC或BAC或BCA,但是你不會得到A的一個破碎的運行與中間的一些B ...

如果您要求由線程2發出的兩個寫入不與由線程1發出的寫入交錯(即ABC和BCA是好的,但BAC不是),那麼你應該使用WSABUF結構數組中的兩個緩衝區對線程2中的WSASend()進行單個調用(或分散/集中寫入),或者需要鎖定寫入調用,以便線程1不能中斷。

+0

太好了。我的意思是前者。行爲是否記錄在某個地方? – sustrik 2010-05-03 18:10:21

+0

不是這樣,儘管我已經使用這個假設重疊I/O服務器已經有10多年了,而這一直是我見過的行爲;你可以把這個「WSASend不應該在不同的線程中同時調用同一個套接字,因爲它可能導致不可預知的緩衝區順序。」從這裏:http://msdn.microsoft.com/en-us/library/ms742203(VS.85).aspx作爲緩衝區本身不分裂的指示;但它是模糊的... – 2010-05-03 19:56:28