2 回答

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

TA貢獻(xiàn)1856條經(jīng)驗(yàn) 獲得超11個(gè)贊
在 Golang 的并發(fā)程序中有兩種通信方式。
同步包:通過共享內(nèi)存進(jìn)行通信。
渠道:通過交流共享記憶。
去推薦
不要通過共享內(nèi)存進(jìn)行通信。相反,通過通信共享內(nèi)存。
- 2 回答
- 0 關(guān)注
- 240 瀏覽
添加回答
舉報(bào)