最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

解決golang sync.Wait()不執(zhí)行的問題

 更新時間:2020年12月23日 10:57:34   作者:Tangs_  
這篇文章主要介紹了解決golang sync.Wait()不執(zhí)行的問題,具有很好的參考價值,希望對大家有所幫助。一起跟隨小編過來看看吧

goroutine 似乎不用解釋太多,可以利用它實現(xiàn)多線程,也可以利用它來實現(xiàn)異步事件。

在使用關(guān)鍵字go的過程中,常常會將用到sync.WaitGroup,如下一段代碼。

package main
import (
	"fmt"
	"sync"
	"time"
)
func Run() {
	var wg = &sync.WaitGroup{}
	go func() {
		wg.Add(1)
		fmt.Println("halo world start")
		time.Sleep(time.Second * 5)
		fmt.Println("halo world end")
		wg.Done()
	}()
	// time.Sleep(time.Millisecond * 5)
	// fmt.Println("server will start")
	wg.Wait()
}
func main() {
	Run()
}
// output:
// 

期待的結(jié)果是打印 halo world start,5秒后打印halo world end,但是結(jié)果就是什么都沒有,并且進程立即就結(jié)束了。

原因

關(guān)鍵字go是異步的,當執(zhí)行到go,不會立即執(zhí)行g(shù)o 后面的內(nèi)容,而且繼續(xù)往下執(zhí)行。此時wg.Add(1)還沒有來得及執(zhí)行,wg.Wait()就已經(jīng)執(zhí)行,即不會發(fā)生等待,進程就結(jié)束了。

怎么解決:

只需要在wg.Wait()前有其他操作,給與足夠的時間讓wg.Add(1)執(zhí)行即可,

方法一、時間等待,在wg.Wait()前加一句time.Sleep(time.Millisecond*5),既不影響性能,也能讓wg.Add(1)來得及執(zhí)行

方法二、有IO操作,在wg.Wait()有其他IO操作,比如fmt.Println("server will start"),原因是std的輸出會將進程從用戶態(tài)轉(zhuǎn)向內(nèi)核態(tài),打印命令發(fā)出后,又切回用戶態(tài),這個狀態(tài)的轉(zhuǎn)換是很有消耗的,wg.Add(1)也就有時間執(zhí)行。

Don't worry

是否有存在擔心,方法一的時間等待,等待的時候不夠長,還是讓wg.Add(1)來不及執(zhí)行。don't worry.

這里涉及到goroutine的調(diào)度問題,go進程在執(zhí)行過程中,必須從goroutine隊列中取出一個來執(zhí)行,當wg.Wait()執(zhí)行前就算執(zhí)行time.Sleep(time.Nanosecond), 一納秒,一…一…一納秒,wg.Add(1)也來得及執(zhí)行,因為主goroutine會被切換到睡眠狀態(tài),go進程必須要取一個線程來執(zhí)行,就會取到wg.Add(1)這個線程,接下來就順理成章了。

同時方法二也是異曲同工,當發(fā)出打印的事件,整個進程都會被切換到就緒態(tài),然后再被cpu執(zhí)行。

補充:【golang】sync.WaitGroup{}的wait()調(diào)用位置不同導致意想不到錯誤

協(xié)程go多了,總覺的天下我有,沒事就喜歡go一個協(xié)程,信手拈來,在項目中寫個如下類似代碼:

  wh := sync.WaitGroup{}
  out := make(chan string)
  go func() {
    wh.Wait()
    close(out)
  }()
  go func() {
    for i := 0; i < 2; i++ {
      wh.Add(1)
      go tt(out)
      wh.Done()
    }
  }()

想著開個協(xié)程去wait所有協(xié)程組,測試一下通了,沒問題,好牛逼,協(xié)程呀??!

可多測試即便就會出現(xiàn):

send close channel

或者協(xié)程定死在某一個,還自已為是的認為自己寫的子方法估計不小心關(guān)閉了channel,找了半天只找到在wg.wait()后進行了關(guān)閉。就這樣扣了好久,還沒想到自己畫蛇添足的錯誤,經(jīng)大佬一指點,原來開一個協(xié)程,還沒等后一個協(xié)程進行wg.add(1)操作,wg.wait()就已經(jīng)過了,關(guān)閉了channel。

只好老老實實寫:

  wh := sync.WaitGroup{}
  out := make(chan string)
  go func() {
    for i := 0; i < 2; i++ {
      wh.Add(1)
      go tt(out)
      wh.Done()
    }
    wh.Wait()
    close(out)
  }()

其實就是一個小小的同步問題,旁觀者清呀?。?!

以上為個人經(jīng)驗,希望能給大家一個參考,也希望大家多多支持腳本之家。如有錯誤或未考慮完全的地方,望不吝賜教。

相關(guān)文章

最新評論

六枝特区| 琼海市| SHOW| 宁波市| 阿克苏市| 乐陵市| 凤冈县| 保亭| 敖汉旗| 乌兰察布市| 祁连县| 绥滨县| 湖南省| 宜春市| 舞钢市| 衡阳市| 蛟河市| 澜沧| 云林县| 伊春市| 高碑店市| 文安县| 洱源县| 泰安市| 泊头市| 昆山市| 子长县| 菏泽市| 寻甸| 余干县| 三河市| 京山县| 兰坪| 上饶市| 东乡族自治县| 阿拉善左旗| 白山市| 微山县| 库尔勒市| 花莲市| 张家港市|