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("小黑")

}

Go语言实现并发(协程)_第1张图片

 

用协程执行

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)
	}
}

Go语言实现并发(协程)_第2张图片

 

channel实现协程通信

Go语言实现并发(协程)_第3张图片

 

      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()
}

 

你可能感兴趣的:(go,协程,并发)