golang協程

最近在使用golang做一個爬蟲,涉及到多線程,golang是沒有多線程的,但是有一種更輕量級能達到類似多線程的效果,協程,golang原生支持協程。
一、怎麼理解協程?
協程是golang語言特性的實現,比線程更低一級的運行方式,它不屬於操作系統功能,不由操作系統分配cpu、內存,而是由golang自己實現運行資源的調度使用。也正是因此執行效率要高於線程。但是協程需要主動讓出控制權後供其他協程運行。
二、如何創建協程?
這裏有2種方式創建:
1、使用go創建

   go sf("a")

2、使用go函數塊創建

go func() {
		sf("b")
	}()

三、使用協程的問題
1、主線程執行完成後直接結束了,此時若協程未執行完成,也會直接結束,毫無徵兆。
下面是個例子

func main() {
	fmt.Println("開始啓動...")
	go sf("a")
	go sf("b")
}

func sf(s string) {
	for i := 0; i < 10; i++ {
		fmt.Println(s+" ->>>", i)
	}
}

運行完成之後根本不會等兩個協程完成運行,主函數直接結束了,如果將代碼改一下
改版1:

func main() {
	fmt.Println("開始啓動...")
	go sf("a")
	go sf("b")
       time.Sleep(time.Duration(2)*time.Minute)
}

在主函數這裏阻塞一下,就可以了,但是這種方式在實際開發中是不可行的,大多不能提前知道協程需要多久運行完成。
改版2:

func main() {
	fmt.Println("開始啓動...")
	var wg = sync.WaitGroup{}
	wg.Add(2)
	go func() {
		sf("a")
		wg.Done()
	}()
	go func() {
		sf("b")
		wg.Done()
	}()
	wg.Wait()
}

這樣運行就ok了,這裏使用了golang的WaitGroup。
理解起來就是創建一個等待的組,可以動態的添加組員的數量,然後在主函數最後一行執行wg.Wait() 來阻塞檢查組員是否都完成了,協程中調用wg.Done()方法進行減一操作告知當前協程完成。
這樣也會帶來新的問題:
1、無法精確控制協程
2、無法準確得知哪個協程完成了或未完成
3、代碼過於原始(繁瑣)

拿java的多線程來理解,這個WaitGroup就像一個線程池,但是池子裏只有計數器,沒有實際對象。在Wait()方法一直在等待WaitGroup的校驗信號,當一個協程完成時使用Done()通知WaitGroup已完成,當所有協程全部通知完成了Wait()釋放,這就是一個非常簡單的消息模型。
在協程這塊,希望golang能優化使用方式,儘可能優雅一些。
找到了一篇講的挺到位的文章,手動傳送門 https://www.cnblogs.com/liang1101/p/7285955.html
歡迎關注我的個人公衆號

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章