Go語言實現併發(協程)

用go命令來執行協程

普通程序

package main

import "fmt"
import "time"

func go_worker(name string){
	for i:=0; i<5; i++{
		fmt.Println("我是一個go協程,我的名字是 ",name)
		time.Sleep(1 * time.Second)
	}
	fmt.Println(name,"執行完畢")
}

func main(){
	go_worker("小黑")

}

 

用協程執行

package main

import "fmt"
import "time"

func go_worker(name string){
	for i:=0; i<5; i++{
		fmt.Println("我是一個go協程,我的名字是 ",name)
		time.Sleep(1 * time.Second)
	}
	fmt.Println(name,"執行完畢")
}

func main(){
	//開闢一個go協程
	go go_worker("小黑")
	//開闢一個go協程
	go go_worker("小白")

	for i:=0; i<10; i++{
		fmt.Println("我是main")
		time.Sleep(1 * time.Second)
	}
}

 

channel實現協程通信

 

      c := make(chan int)

你想傳遞整型就int,想傳遞字符串就string

package main

import "fmt"

func worker(c chan int) {
	//從channel c中得到數據
	num := <-c
	fmt.Println("得到了管道中的數據 ", num)
}

func main() {
	//創建⼀個channel
	c := make(chan int)
	
	//開闢一個協程,去執行worker函數
	go worker(c)

	//main向channel c中寫數據
	c <- 1

	fmt.Println("我是main")
}

 

等待組sync.WaitGroup

       多線程編程中,經常會遇到這樣的一種場景:main函數中爲了等待其他線程執行完,在return之前都要執行sleep以爭取更多的時間給其他線程執行.

      主線程爲了等待goroutine都運行完畢,不得不在程序的末尾使用time.Sleep() 來睡眠一段時間,等待其他線程充分運行。對於簡單的代碼,100個for循環可以在1秒之內運行完畢,time.Sleep() 也可以達到想要的效果。但是對於實際場景來說,大多無法預知for循環內代碼運行時間的長短,因此1秒可能是不夠的。所以睡眠也就達不到我們想要的效果。

 

      WaitGroup(等待組)就是用來解決這種問題的,它主要用於同步多個協程間的狀態(例如等待所有協程都執行完)。

      在WaitGroup 對象實現中,內部有一個計數器,最初從0開始,它有三個方法:

  • Add():計數器加一
  • Done():計數器減一
  • Wait():等待計數器清零

 

執行Wait方法的函數在等待組內部計數器不爲0的時候回阻塞,一旦計數器爲0了,程序就會繼續往下執行。

 

func main() {
    wg := sync.WaitGroup{}
    wg.Add(100)
    for i := 0; i < 100; i++ {
        go func(i int) {
            fmt.Println(i)
            wg.Done()
        }(i)
    }
    wg.Wait()
}

 

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