亚洲在线久爱草,狠狠天天香蕉网,天天搞日日干久草,伊人亚洲日本欧美

為了賬號安全,請及時綁定郵箱和手機立即綁定
已解決430363個問題,去搜搜看,總會有你想問的

為什么 Java 和 Go 都在寫之前鎖定套接字?

為什么 Java 和 Go 都在寫之前鎖定套接字?

Go
紅顏莎娜 2022-07-18 17:09:23
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 行代碼,顯然不是原子的。它使用mallocand執行分配和釋放內存free等操作,并且涉及相當多的非平凡邏輯。在那個時候,它調用的用于實際發送數據的函數是否NET_Send直接轉換為每個支持的平臺上的系統調用都不再重要了。

要點是:實現NET_Send在循環中調用 this -function。因此,無論這是否是單獨的線程安全的,如果它被多個線程同時調用,輸出將是交錯的(最好的情況)。


查看完整回答
反對 回復 2022-07-18
?
慕碼人2483693

TA貢獻1860條經驗 獲得超9個贊

好的,假設沒有鎖定機制,并且兩個并發線程/進程正在向套接字寫入一些數據。讓我們舉一個過于簡單的例子。


Java 應用程序想要寫:“你好!你好嗎?”。


Go 應用想寫:“再見?!?/p>


這兩個應用程序都試圖同時寫入。


您期望的輸出是:


Hello! How are you?

See you later.

但是,您很有可能會得到類似的東西。


HellSee o! How  See you are later.

 you?

每當資源在不同的進程/線程之間共享并且沒有適當的鎖定機制時。遇到不一致和意外行為的可能性很高。


查看完整回答
反對 回復 2022-07-18
  • 2 回答
  • 0 關注
  • 148 瀏覽
慕課專欄
更多

添加回答

舉報

0/150
提交
取消
微信客服

購課補貼
聯系客服咨詢優惠詳情

幫助反饋 APP下載

慕課網APP
您的移動學習伙伴

公眾號

掃描二維碼
關注慕課網微信公眾號