第七色在线视频,2021少妇久久久久久久久久,亚洲欧洲精品成人久久av18,亚洲国产精品特色大片观看完整版,孙宇晨将参加特朗普的晚宴

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

Go 中的多線程。有人可以向我解釋這些答案嗎?

Go 中的多線程。有人可以向我解釋這些答案嗎?

C#
繁星點點滴滴 2021-12-06 15:00:31
我在模擬考試中遇到了兩個問題。我得到了答案,但無法弄清楚它們背后的原理。我將首先發(fā)布代碼,然后發(fā)布問題和答案。也許有人會這么好心地向我解釋答案?package mainimport "fmt"func fact(n int, c chan int, d chan int) {    k := /* code to compute factorial of n */    z := <- d    c <- k + z    d <- z + 1}func main() {    r := 0    c := make(chan int)    d := make(chan int)    for i = 0 ; i < N ; i++ {        go fact(i,c,d)    }    d <- 0    for j = 0 ; j < N ; j++ {        r = r + <-c    }    fmt.Printf("result = %d\n",r)}第一個問題是:如果我們省略主程序中的“d <- 0”行,程序會怎樣,為什么?老師的回答是:所有線程和主線程的狀態(tài)都被阻塞。第二個問題是:如果交換fact過程的前兩行,對整個程序的效率有什么影響?答案是:所有線程都將按順序運行。每個線程只有在完成時才會觸發(fā)另一個線程。
查看完整描述

2 回答

?
GCT1015

TA貢獻1827條經(jīng)驗 獲得超4個贊

最好不要將其視為“多線程”。Go 為并發(fā)提供了直接的便利,而不是為線程提供了便利。它碰巧使用線程來實現(xiàn)其并發(fā)性,但這是一個實現(xiàn)細節(jié)。參見 Rob Pike 的演講,Concurrency is not parallelism進行更深入的討論。


您問題的關鍵是默認情況下通道是同步的(如果它們在構建過程中沒有被緩沖)。當一個 goroutine 寫入一個通道時,它會阻塞,直到另一個 goroutine 從該通道讀取。所以當這一行執(zhí)行時:


z := <- d

在此行執(zhí)行之前,它無法繼續(xù):


d <- 0

如果d頻道上沒有可用的價值,fact則永遠不會繼續(xù)。這對你來說很明顯。但反過來也是如此。在從d通道讀取某些內(nèi)容之前,主 goroutine 無法繼續(xù)。通過這種方式,無緩沖通道提供了跨并發(fā) goroutine 的同步點。


同樣,主循環(huán)無法繼續(xù),直到某個值出現(xiàn)在 上c。我發(fā)現(xiàn)使用兩個手指并指向每個 goroutine 中的當前代碼行很有用。前進一根手指,直到進入頻道操作。然后推進另一個,直到它到達一個通道操作。如果您的手指指向同一通道上的讀取和寫入,則您可以繼續(xù)。如果他們不是,那么你就陷入了僵局。


如果你仔細考慮一下,你就會發(fā)現(xiàn)一個問題。該程序泄漏了一個 goroutine。


func fact(n int, c chan int, d chan int) {

    k := /* code to compute factorial of n */

    z := <- d // (1)

    c <- k + z

    d <- z + 1 // (2)

}

在 (2) 處,我們嘗試寫入d. 什么將允許它繼續(xù)進行?另一個 goroutine 從d. 請記住,我們啟動了Ngoroutines,并且它們都試圖從d. 只有其中之一會成功。其他人將在 (1) 處阻塞,等待某些東西出現(xiàn)在 上d。當?shù)谝粋€到達(2)時會發(fā)生這種情況。然后那個 goroutine 退出,一個隨機的 goroutine 將繼續(xù)。


但是會有一個最終的 goroutine 永遠無法寫入d并且會泄漏。為了解決這個問題,需要在 final 之前添加以下內(nèi)容Printf:


<-d

這將允許最后一個 goroutine 退出。


查看完整回答
反對 回復 2021-12-06
?
繁華開滿天機

TA貢獻1816條經(jīng)驗 獲得超4個贊

如果我們省略主程序中的“d <- 0”行,程序會怎樣,為什么?

有了這行代碼,每個 goroutine 開始go fact(...)都會等待來自 channel 的東西,在 statement 阻塞z := <- d。

fact()函數(shù)對d頻道的內(nèi)容沒有實際影響- 它刪除一些內(nèi)容并添加一些內(nèi)容。因此,如果通道中沒有任何內(nèi)容,則不會有任何進展,程序?qū)⑾萑虢┚帧?/p>

從同一通道讀取和寫入的 goroutine 要求死鎖 - 在現(xiàn)實生活中避免!

如果交換fact過程的前兩行,對整個程序的效率有什么影響?

在進行冗長的階乘計算之前,fact()例程將等到它從d通道中獲得令牌。

因為d通道中一次只有一個令牌在播放,這意味著每個 goroutine 只會在收到令牌時進行昂貴的計算,從而有效地將它們序列化。

與最初一樣,昂貴的階乘計算是在等待令牌之前并行完成的。

在實踐中,這不會像您希望的那樣工作,因為 goroutine 不是預先調(diào)度的,僅用于阻塞操作和函數(shù)調(diào)用。


查看完整回答
反對 回復 2021-12-06
  • 2 回答
  • 0 關注
  • 218 瀏覽

添加回答

舉報

0/150
提交
取消
微信客服

購課補貼
聯(lián)系客服咨詢優(yōu)惠詳情

幫助反饋 APP下載

慕課網(wǎng)APP
您的移動學習伙伴

公眾號

掃描二維碼
關注慕課網(wǎng)微信公眾號