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

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

多個 goroutine 會同時調用 Conn 上的方法嗎?

多個 goroutine 會同時調用 Conn 上的方法嗎?

Go
Cats萌萌 2022-01-17 19:55:11
我的程序是這樣的:func handle(conn net.Conn) {    msg := "hello, world!"    for i:= 0; i< 100000; i++ {        go func() {            err := write(conn, msg)        }    }}func write(conn net.Conn, msg string) error {    mlen := fmt.Sprintf("%04d", len(msg))    _, err := conn.Write([]byte(mlen + msg))    return err}該程序將同時運行 100000 個 goroutine,并且所有 goroutine 將向同一個連接發送消息。我懷疑服務器會收到類似“hellohelloworldworld”的錯誤消息,但是當程序在我的 Ubuntu 14.04LTS 中運行時沒有問題。那么,多個 goroutine 會同時調用 Conn 上的方法嗎?=========================================================================我怎樣才能保持Write方法的原子性?
查看完整描述

2 回答

?
PIPIONE

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

該文檔指出:

多個 goroutine 可以同時調用 Conn 上的方法。

沒有提到每個單獨的寫入是否是原子的。雖然當前的實現可以確保每次調用都Write在下一次調用開始之前完全發生,但語言規范中并不能保證。


查看完整回答
反對 回復 2022-01-17
?
ABOUTYOU

TA貢獻1812條經驗 獲得超5個贊

這個答案意味著寫入是原子的。

io.Write 接口的具體實現者需要在發生部分寫入時返回錯誤。net.Conn 在 unix 上通過獲取鎖并在循環中調用 write 來處理這個問題,直到整個緩沖區都被寫入。在 Windows 上,它調用 WSASend,它保證發送整個緩沖區,除非發生錯誤。但是文檔確實有這個警告

對 WSASend 的調用順序也是緩沖區傳輸到傳輸層的順序。WSASend 不應該在同一個面向流的套接字上同時從不同的線程調用,因為一些 Winsock 提供者可能會將一個大的發送請求分成多個傳輸,這可能會導致來自同一個面向流的多個并發發送請求的意外數據交錯插座。

這意味著它不一定是原子的,除非 Go 獲得了一個互斥體——它確實做到了。

所以基本上它在實踐中是原子的??梢韵胂螅粋€實現可以將線程安全定義為不崩潰,并通過解鎖調用 write 周圍的互斥鎖(或在 Windows 上根本不獲取它)來允許交錯寫入。但這對我來說沒有意義,而且開發人員清楚地表明了相反的意圖。


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

添加回答

舉報

0/150
提交
取消
微信客服

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

幫助反饋 APP下載

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

公眾號

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