Go internal/poll/fd_unix.go 代碼在這里// Write implements io.Writer.func (fd *FD) Write(p []byte) (int, error) { if err := fd.writeLock(); err != nil { return 0, err } defer fd.writeUnlock() ......}java代碼java.net.SocketOutputStream#socketWrite在這里 private void socketWrite(byte b[], int off, int len) throws IOException { if (len <= 0 || off < 0 || len > b.length - off) { if (len == 0) { return; } throw new ArrayIndexOutOfBoundsException("len == " + len + " off == " + off + " buffer length == " + b.length); } FileDescriptor fd = impl.acquireFD(); try { socketWrite0(fd, b, off, len); } catch (SocketException se) { ......我不知道為什么我們需要鎖定它。另一個問題是 syscall.Write 等效于 <unistd.h> 用 C 編寫嗎?
2 回答

婷婷同學_
TA貢獻1844條經驗 獲得超8個贊
好吧,只回答 Java 部分:
既然我們已經在討論實現細節,為什么要停留在 Java 級別呢?本機方法socketWrite0的 OpenJdk 實現的 C 源代碼跨越約 70 行代碼,顯然不是原子的。它使用malloc
and執行分配和釋放內存free
等操作,并且涉及相當多的非平凡邏輯。在那個時候,它調用的用于實際發送數據的函數是否NET_Send
直接轉換為每個支持的平臺上的系統調用都不再重要了。
要點是:實現NET_Send
在循環中調用 this -function。因此,無論這是否是單獨的線程安全的,如果它被多個線程同時調用,輸出將是交錯的(最好的情況)。

慕碼人2483693
TA貢獻1860條經驗 獲得超9個贊
好的,假設沒有鎖定機制,并且兩個并發線程/進程正在向套接字寫入一些數據。讓我們舉一個過于簡單的例子。
Java 應用程序想要寫:“你好!你好嗎?”。
Go 應用想寫:“再見?!?/p>
這兩個應用程序都試圖同時寫入。
您期望的輸出是:
Hello! How are you?
See you later.
但是,您很有可能會得到類似的東西。
HellSee o! How See you are later.
you?
每當資源在不同的進程/線程之間共享并且沒有適當的鎖定機制時。遇到不一致和意外行為的可能性很高。
- 2 回答
- 0 關注
- 148 瀏覽
添加回答
舉報
0/150
提交
取消