亚洲香蕉成人av网站在线观看_欧美精品成人91久久久久久久_久久久久久久久久久亚洲_热久久视久久精品18亚洲精品_国产精自产拍久久久久久_亚洲色图国产精品_91精品国产网站_中文字幕欧美日韩精品_国产精品久久久久久亚洲调教_国产精品久久一区_性夜试看影院91社区_97在线观看视频国产_68精品久久久久久欧美_欧美精品在线观看_国产精品一区二区久久精品_欧美老女人bb

首頁 > 編程 > Golang > 正文

Golang 探索對Goroutine的控制方法(詳解)

2020-04-01 19:00:27
字體:
來源:轉載
供稿:網友

前言

在golang中,只需要在函數調用前加上關鍵字go即可創建一個并發任務單元,而這個新建的任務會被放入隊列中,等待調度器安排。相比系統的MB級別線程棧,goroutine的自定義棧只有2KB,這使得我們能夠輕易創建上萬個并發任務,如此對性能提升不少。但隨之而來的有以下幾個問題:

如何等待所有goroutine的退出

如何限制創建goroutine的數量(信號量實現)

怎么讓goroutine主動退出

探索——如何從外部殺死goroutine

本文記錄了筆者就以上幾個問題進行探究的過程,文中給出了大部分問題的解決方案,同時也拋出了未解決的問題,期待與各位交流:p

準備

開始之前先定義一個常量const N=100以及一個HeavyWork函數,假定該函數具有極其冗長、復雜度高、難以解耦的特性

func HeavyWork(id int) { rand.Seed(int64(id)) interval := time.Duration(rand.Intn(3)+1) * time.Second time.Sleep(interval) fmt.Printf("HeavyWork %-3d cost %v/n", id, interval)}

以上定義的內容將在之后的代碼中直接使用以縮減篇幅,大部分完整代碼可在 Github: explore-goroutine 中找到

如何等待所有goroutine的退出

"Do not communicate by sharing memory; instead, share memory by communicating"——GO的一大設計哲學《Share Memory By Communicating》

翻譯成中文就是,用通信來共享內存數據,而不要通過共享內存數據來進行通信。

Go中的goroutines和channel提供了一種優雅而獨特的結構化并發軟件的方法,我們可以利用通道(channel)的特性,來實現當前等待goroutine的操作。但是channel并不是當前這個場景的最佳方案,用它來實現的方式是稍顯笨拙的,需要知道確定個數的goroutine,同時稍不注意就極易產生死鎖,代碼如下:

// "talk is cheap, show me the code."func main() { waitChan := make(chan int, 1) for i := 0; i < N; i++ {  go func(n int) {   HeavyWork(n)   waitChan <- 1  }(i) } cnt := 0 for range waitChan {  cnt++  if cnt == N {   break  } } close(waitChan) fmt.Println("finished")}

上述代碼使用了一個緩存大小為1的通道(channel),創建N個goroutine用于運行HeavyWork,每個任務完成后向waitChan寫入一個數據,在收到N個完成信號后退出。

但事實上比較優雅的方式是使用go標準庫sync,其中提供了專門的解決方案sync.WaitGroup用于等待一個goroutines集合的結束

// "talk is cheap, show me the code."func main() { wg := sync.WaitGroup{} for i := 0; i < N; i++ {  wg.Add(1)  go func(n int) {   defer wg.Done()   HeavyWork(n)  }(i) } wg.Wait() fmt.Println("finished")}

關于sync.WaitGroup的具體使用請參照官方文檔[GoDoc] sync.WaitGroup ,這里不再贅述

如何限制goroutine的創建數量(信號量實現)

信號量(Semaphore),有時被稱為信號燈,是在多線程環境下使用的一種設施,是可以用來保證兩個或多個關鍵代碼段不被并發調用。

其中V操作會增加信號量的數值即釋放資源,而P操作會減少它即占用資源

那么非常容易想到的就是利用channel(通道)緩存有限的特性,它允許我們可以自實現一個簡單的數量控制,就如同使用信號量一般,在這基礎再加上前面提到的sync.WaitGroup,我們可以打出一套組合拳,提供可阻塞的信號量PV操作,能夠實現固定創建goroutine數量并且支持等待當前goroutine的退出。結構體定義如下:

type Semaphore struct { Threads chan int Wg  sync.WaitGroup}

而P操作只需在channel中加入一個元素同時調用WaitGroup.Add即可,這一操作完成對資源的申請

func (sem *Semaphore) P() { sem.Threads <- 1 sem.Wg.Add(1)}

相反則是V操作,進行資源的釋放

func (sem *Semaphore) V() { sem.Wg.Done() <-sem.Threads}

Wait則阻塞等待直到當前所有資源都歸還,直接調用WaitGroup的方法即可

func (sem *Semaphore) Wait() { sem.Wg.Wait()}

完整代碼可以在 Github: semaphore 中查看

利用上面的信號量就可以做到,在一個時刻的goroutines數量不會超過信號量值的大小,而某個goroutine退出后將返還占用的信號量,而正在等待的goroutine就可以立即申請,下圖形象地展現了運行時的狀態

Golang,Goroutine,控制

怎么讓goroutine主動退出

對于goroutine的主動退出,比較友好的做法就是循環監聽一個channel,通過類似信號的方式來告知goroutine的”該退出了“,然后goroutine自己主動退出,這種做法在網上十分常見,也是Golang官方推薦的做法,思想也很簡單。

func main() { ok, quit := make(chan int, 1), make(chan int, 1) go func() {  i := 0  for {   select {   case <-quit:    ok <- 1    return   default:    HeavyWork(i)    i++   }  } }() time.Sleep(5 * time.Second) quit <- 1 <-ok}

運行結果如下圖

Golang,Goroutine,控制

探索——如何從外部殺死goroutine

上面講了一些關于goroutines和channel的簡單使用,接下來終于寫到本文的重點了。筆者并沒有解決如何從外部殺死一個goroutine,但記錄了嘗試“殺死”中的可行或不可行方法,希望對各位有所幫助。

因為近期在開發中遇到這樣一個問題,當一個函數是極其冗長、復雜度高、難以解耦的順序結構代碼時(例如某個極其復雜無循環結構的加密算法),而且由于數據量巨大,需要反復調用該函數,由于每運行一次,程序都會消耗大量的時間、空間,那么當一個任務已經被用戶拋棄時,如何才能拋棄仍在做著無用功的goroutine?

為了達到“殺死goroutine”的目的,筆者做了很多嘗試,如

select結構(條件實現)

panic退出機制(失敗)

獲取pid殺死(失敗)

ptrace單步調試(失?。?/p>

...(失?。?/p>

利用select語句實現

關于“如何殺死goroutine”,網上有一部分答案就是利用select實現的,但是這種方式實現的代碼并不適用于服務類的程序,但是對于一般非服務類程序的確能夠實現殺死goroutine的效果,代碼如下:

func main() { wrapper := func() chan int {  c := make(chan int)  go func() {   HeavyWork(0)   c <- 1  }()  return c } select { case <-wrapper(): case <-time.After(1 * time.Second):  fmt.Println("time limit exceed") } // time.Sleep(3 * time.Second)}

Golang,Goroutine,控制

但是一旦主函數沒有立即退出,而是作為某種服務而繼續運行時,這里刪除了main函數的最后一行注釋time.Sleep(3 * time.Second),延遲三秒后退出。可以看見盡管已經超時并輸出"time limit exceed"之后,HeavyWork在main函數沒退出前依舊在運行。效果如下

Golang,Goroutine,控制

所以使用select-timeout的方式比較適合實時退出類型的程序,能夠實現一定程度上的并發控制,

小結

就目前而言,還沒有完美的方案來解決控制goroutine的問題,事實上Go似乎并不允許和推薦人們直接控制goroutine,所以暫時還無法做到從外部直接控制goroutine的生命周期,所以比較推薦的做法還是只能通過goroutine主動退出的方法,循環監聽channel,在發出退出信號后最多只消耗一輪資源后就退出,但這就要求該代碼具有循環結構否則就很難使用。有更好解決方案的朋友,請務必告訴我!

以上這篇Golang 探索對Goroutine的控制方法(詳解)就是小編分享給大家的全部內容了,希望能給大家一個參考,也希望大家多多支持VEVB武林網。


發表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發表
亚洲香蕉成人av网站在线观看_欧美精品成人91久久久久久久_久久久久久久久久久亚洲_热久久视久久精品18亚洲精品_国产精自产拍久久久久久_亚洲色图国产精品_91精品国产网站_中文字幕欧美日韩精品_国产精品久久久久久亚洲调教_国产精品久久一区_性夜试看影院91社区_97在线观看视频国产_68精品久久久久久欧美_欧美精品在线观看_国产精品一区二区久久精品_欧美老女人bb
北条麻妃一区二区三区中文字幕| 影音先锋欧美在线资源| 精品久久久久国产| 国产欧美在线播放| 九九热这里只有在线精品视| 亚洲欧洲日本专区| 91精品啪aⅴ在线观看国产| 国产精品av在线| 久久久久久久久网站| 国产午夜精品理论片a级探花| yw.139尤物在线精品视频| 久久婷婷国产麻豆91天堂| 在线亚洲男人天堂| 久久人人爽人人爽人人片亚洲| 性欧美暴力猛交69hd| 亚洲美女中文字幕| 91在线高清视频| 国产欧美日韩丝袜精品一区| 日本免费在线精品| 久久久精品一区| 欧美电影免费看| 亚洲欧美精品中文字幕在线| 亚洲品质视频自拍网| 欧美日韩另类在线| 久久精品小视频| 成人a在线视频| 成人激情视频在线观看| 日韩欧美国产网站| 日本最新高清不卡中文字幕| 久久五月天综合| 亚洲精品久久久久| 亚洲摸下面视频| 欧美大尺度在线观看| 91国产中文字幕| 国产精品欧美激情在线播放| 久久久噜久噜久久综合| 亚洲精品视频久久| 国产精品爱啪在线线免费观看| 欧美激情精品久久久久久| 91日韩在线视频| 亚洲第一福利视频| 欧美xxxx18性欧美| 色噜噜国产精品视频一区二区| 国产不卡精品视男人的天堂| 国产日韩在线看| 一本色道久久88精品综合| 国产日本欧美一区二区三区在线| 欧美精品激情blacked18| 91高清在线免费观看| 亚洲国产精彩中文乱码av在线播放| 久久久久久久久爱| 亚洲国产高清福利视频| 国产精品午夜一区二区欲梦| 国模精品系列视频| 日韩成人在线观看| 亚洲综合中文字幕68页| 国产91精品久| 粗暴蹂躏中文一区二区三区| 欧美高清激情视频| 欧美成人免费全部| 57pao国产精品一区| 日韩欧美成人精品| 国产一区二区三区三区在线观看| 一个人看的www久久| 国产精品久久久久久久av大片| 成人欧美一区二区三区在线湿哒哒| 欧美电影在线观看| 国模吧一区二区三区| 91在线无精精品一区二区| 成人黄色片网站| 欧美一区二区色| 国产精品xxx视频| 欧美日韩国产色| 欧美性xxxx极品hd欧美风情| 热久久美女精品天天吊色| 午夜精品一区二区三区在线视频| 成人美女av在线直播| 国产美女精品视频| 欧美高清视频一区二区| 日韩中文字幕在线观看| 日韩欧美亚洲综合| 亚洲www在线| 中文字幕欧美专区| 欧美性极品xxxx做受| 成人免费观看a| 亚洲人成五月天| 欧美大片va欧美在线播放| 欧美高清性猛交| 亚洲精品美女久久| 日韩美女视频免费在线观看| 色妞欧美日韩在线| 91理论片午午论夜理片久久| 亚洲有声小说3d| 国产精品久久久久久久久| 午夜精品一区二区三区在线视频| 国产精品丝袜久久久久久不卡| 一二美女精品欧洲| 欧美日韩中文字幕在线| 亚洲黄色av网站| 中文字幕av一区二区三区谷原希美| 国内精品久久久久伊人av| 中文字幕久热精品视频在线| 欧美午夜视频在线观看| 97国产一区二区精品久久呦| 久久在线免费观看视频| 九九热视频这里只有精品| 免费91麻豆精品国产自产在线观看| 欧美丰满少妇xxxx| 欧美一级淫片播放口| 一区二区av在线| 欧美成人在线免费| 在线观看精品国产视频| 精品欧美aⅴ在线网站| 精品亚洲国产成av人片传媒| 成人两性免费视频| 国产成人在线一区二区| 亚洲丁香婷深爱综合| 国产精品久久久久久久久久小说| 日韩最新中文字幕电影免费看| 在线丨暗呦小u女国产精品| 亚洲欧美日本伦理| 亚洲丁香婷深爱综合| 国内精品久久久久影院 日本资源| 成人亚洲综合色就1024| 成人一区二区电影| 96pao国产成视频永久免费| 91中文在线观看| 欧美限制级电影在线观看| 日韩大胆人体377p| 91禁国产网站| 在线精品视频视频中文字幕| 久久天天躁狠狠躁夜夜av| 日韩成人在线观看| 91天堂在线观看| 日韩欧美主播在线| 日韩成人在线视频| 亚洲最大成人网色| 国产亚洲精品久久久优势| 国产精国产精品| 国产精品入口日韩视频大尺度| 中文字幕av一区二区| 欧美日韩国内自拍| 亚洲一区二区黄| 欧美国产日韩一区二区三区| 亚洲一区二区三区毛片| 日韩理论片久久| 亚洲人精品午夜在线观看| 欧美视频在线观看免费网址| 欧美日韩中文字幕| 久久久精品久久久久| 久久成人av网站| 欧美午夜无遮挡| 国产成+人+综合+亚洲欧美丁香花| 亚洲欧洲美洲在线综合| 日韩在线视频观看| 中文字幕日韩av综合精品| 欧美贵妇videos办公室| 国产精品视频一区二区高潮| 97在线视频国产| 成人午夜激情网| 精品激情国产视频| 亚洲人成电影在线| 国产98色在线| 欧美性猛交xxxx|