2 回答

TA貢獻1111條經驗 獲得超0個贊
通道從根本上不同于互斥體。
一個有足夠細節的正確答案會太長,所以讓我們只介紹主要亮點,特別是在 Go 頻道方面:
Go 通道提供并發例程(goroutines)之間的類型化數據傳輸。
A為并發例程(goroutines)之間的共享內存sync.Mutex提供互斥。
數據傳輸表示復制某個類型 T 的值。Goroutine A 將一個值放入通道中:
var v T // v is a value of type T
...
ch <- v // put v's value into the channel
何時以及是否嘗試放入v 通道塊,以及如果您愿意,您可以對此做些什么,有點復雜,但如果通道是緩沖的,那么至少一些值可以立即進入它而沒有任何阻塞,以便發送 goroutine 可以繼續。如果通道是無緩沖的,則發送方會阻塞,直到某個接收方 goroutine 正在積極等待一個值。(有時這是可取的,有時則不是。)
同時,goroutine B 從通道中取出一個值:
var w T // w is also a value of type T
...
w <- ch
要不就:
w :=<- ch
同樣,何時以及是否會阻塞,您可以做什么,何時應該做某事等,可能會變得復雜;但在簡單的情況下,這會等待有一個可用的值——讓某個 goroutine 執行ch <- v,或者如果通道被緩沖,則已經完成它——然后它將放入w通道中的值復制到變量中。變量v可能已經改變,甚至被完全破壞。該值已安全地存儲在通道中,現在已從通道中刪除并放入變量w中。
Go 通道有一些額外的功能,例如關閉通道的能力,它可以防止進一步的寫入,并將“數據結束”通知傳遞給讀取操作。這可以通過單值讀取 ( ) 進行測試,并在循環w, ok <- ch中進行隱式測試。for w := range ch
sync.Mutex相比之下,實例只是讓您調用Lockand Unlock。它不保存任何排隊的值(如緩沖通道那樣),甚至沒有一種類型(除了sync.Mutex它自己),可以防止您意外地將 a 發送float到期望的東西string或其他東西。這個鎖的存在讓兩個或多個 goroutine 使用共享內存區域來完成某些事情。
通道的運行時實現很可能需要某種互斥鎖。這不一定是sync.Mutex它本身:任何提供足夠互斥的東西就足夠了。在您可能正在使用的 Go 通道實現中,它不是一個專門的運行時互斥鎖sync.Mutex,而是一個專用的運行時互斥鎖。(請注意,此鏈接指向特定行,并且該行可能會隨著時間的推移而過時。)由于某些通道代碼是由編譯器本身直接生成的,因此不應假定此處的運行時例程正在使用:您的編譯器可能與眾不同。然而,研究這個特定的實現可能會讓您對您可以使用通道做什么有所啟發。
互斥鎖通常比通道簡單得多。要查看示例,請將上述通道實現中的代碼量(不包括編譯器的內聯插入)與此特定 Go 實現的sync.Mutex源代碼進行比較。

TA貢獻1856條經驗 獲得超11個贊
在 Golang 的并發程序中有兩種通信方式。
同步包:通過共享內存進行通信。
渠道:通過交流共享記憶。
去推薦
不要通過共享內存進行通信。相反,通過通信共享內存。
- 2 回答
- 0 關注
- 233 瀏覽
添加回答
舉報