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

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

了解goroutines

了解goroutines

Go
HUWWW 2021-04-25 10:21:33
我試圖了解Go中的并發性。特別是,我編寫了以下線程不安全程序:package mainimport "fmt"var x = 1func inc_x() { //test  for {    x += 1  }}func main() {  go inc_x()  for {    fmt.Println(x)  }}我知道我應該使用渠道來防止與發生競爭x,但這不是重點。該程序打印1,然后似乎永遠循環(不再打印任何內容)。我希望它能打印出無限的數字列表,可能由于競態條件而跳過某些數字并重復其他數字(或更糟糕的是,在更新數字時打印數字inc_x)。我的問題是:為什么程序只打印一行?只是要清楚一點:在這個玩具示例中,我并不是故意使用渠道。
查看完整描述

3 回答

?
慕的地8271018

TA貢獻1796條經驗 獲得超4個贊

關于Go的goroutine,有幾點需要牢記:

  1. 從Java或C ++線程的意義上來說,它們不是線程

  2. go運行時在系統線程之間多路復用goroutines

    • 系統線程的數量由環境變量控制,GOMAXPROCS我認為當前默認為1。將來可能會改變

  3. goroutine屈服于其當前線程的方式由幾種不同的結構控制

    • select語句可以產生控制回線

    • 通道上發送可以將控制權交還給線程

    • 進行IO操作可以將控制權交還給線程

    • runtime.Gosched() 顯式地將控制權交還給線程

您看到的行為是因為main函數從不屈服于線程,而是參與了繁忙的循環,并且因為只有一個線程,所以main循環無處運行。


查看完整回答
反對 回復 2021-05-10
?
阿波羅的戰車

TA貢獻1862條經驗 獲得超6個贊

根據這個和這個,幾個電話不能CPU密集型夠程的過程中調用(如果夠程從不屈服于調度)。如果其他Goroutine需要阻塞主線程,這可能會導致它們掛起(例如,所使用的write()syscall就是這種情況fmt.Println())


我發現的解決方案涉及到調用runtime.Gosched()與CPU綁定的線程,以將其返回給調度程序,如下所示:


package main


import (

  "fmt"

  "runtime"

)


var x = 1


func inc_x() {

  for {

    x += 1

    runtime.Gosched()

  }

}


func main() {

  go inc_x()

  for {

    fmt.Println(x)

  }

}

因為你只有在夠程執行一個操作,runtime.Gosched()是被稱為非常頻繁。調用runtime.GOMAXPROCS(2)init的速度快一個數量級,但是如果您做的事情比增加數字復雜得多(例如,處理數組,結構,映射等),則調用init會非常不安全。


在那種情況下,最佳實踐可能是使用渠道來管理對資源的共享訪問。


查看完整回答
反對 回復 2021-05-10
?
鴻蒙傳說

TA貢獻1865條經驗 獲得超7個贊

這是兩件事的相互作用。一個默認情況下,Go僅使用單個內核,第二個Go必須協同計劃goroutine。您的函數inc_x不會屈服,因此會壟斷所使用的單個內核。消除這些條件中的任何一個都將導致您期望的輸出。

說“核心”有點含糊。Go實際上可能在后臺使用了多個內核,但是它使用一個名為GOMAXPROCS的變量來確定線程數,以調度執行非系統任務的goroutine。如FAQEffective Go中所述,默認值為1,但可以使用環境變量或運行時函數將其設置為更高的值。這可能會提供您期望的輸出,但前提是您的處理器具有多個內核。

獨立于內核和GOMAXPROCS,您可以為運行時的goroutine調度程序提供完成其工作的機會。調度程序無法搶占正在運行的goroutine,而必須等待它返回運行時并請求某些服務,例如IO,time.Sleep()或runtime.Gosched()。在inc_x中添加類似的內容會產生預期的輸出。運行main()的goroutine已經通過fmt.Println請求服務,因此,由于這兩個goroutine現在定期屈服于運行時,因此它可以進行某種公平的調度。


查看完整回答
反對 回復 2021-05-10
  • 3 回答
  • 0 關注
  • 261 瀏覽
慕課專欄
更多

添加回答

舉報

0/150
提交
取消
微信客服

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

幫助反饋 APP下載

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

公眾號

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