Skip to main content

并发

[TOC]

协程

创建协程

创建协程只要加 go 关键字就行了
比如 main函数里这么写

    go gorotine.Loop()
go gorotine.Loop()
time.Sleep(time.Second * 3 )

调用的函数

package gorotine

import (
"fmt"
"time"
)

func Loop() {
for i :=1;i<10;i++ {
fmt.Print(i,",")
time.Sleep(time.Nanosecond)
}
}

输出

1,1,2,2,3,3,4,4,5,5,6,6,7,7,8,8,9,9,

交出协程

如果协程中有一个for死循环, 将会无法退出协程,使用 runtime.Gosched() 交出协程

runtime.Gosched()

CPU常规设置

设置多核

runtime.NumCPU() 读取CPU的核心数

runtime.GOMAXPROCS(runtime.NumCPU()) 设置CPU的核心数

协程通信

常使用通道

例子1

var chanInt chan int = make(chan int,10)

/发送数据
func Send() {
chanInt <- 1
time.Sleep(time.Second*1)
chanInt <- 2
time.Sleep(time.Second*1)
chanInt <- 3
time.Sleep(time.Second*1)
chanInt <- 4
time.Sleep(time.Second*1)

}
//接受数据
func Receive() {
num := <- chanInt
fmt.Println("Num: ",num)
num = <- chanInt
fmt.Println("Num: ",num)
num = <- chanInt
fmt.Println("Num: ",num)
num = <- chanInt
fmt.Println("Num: ",num)
}

调用

    go gorotine.Send()
go gorotine.Receive()
time.Sleep(time.Second * 4 )

例子2

var chanInt chan int = make(chan int,10)
var timeout chan bool = make(chan bool)

//发送数据
func Send() {
time.Sleep(time.Second*1)
chanInt <- 1
time.Sleep(time.Second*1)
chanInt <- 2
time.Sleep(time.Second*1)
chanInt <- 3
time.Sleep(time.Second*1)
chanInt <- 4
time.Sleep(time.Second*1)
timeout <- true
}
//接受数据
func Receive() {
for {
select {
case num := <- chanInt:
fmt.Println("Num:", num)
case <-timeout:
fmt.Println("timeout...")
}
}
}

调用

    go gorotine.Send()
go gorotine.Receive()
time.Sleep(time.Second *6 )

协程同步(同步等待组)

  • Add 增加一条记录
  • Done 减少一条记录
  • Wait 等待记录为0的时候继续往下执行
  • 原理就是计数

var WG sync.WaitGroup
//读取数据
func Read() {
for i:=0;i<3 ;i++{
WG.Add(i)
}
}
//写入数据
func Write() {
for i:=0;i<3 ;i++{
time.Sleep(time.Second*1)
fmt.Println("Done ->",i)
WG.Done()
}
}

调用

    gorotine.Read()
go gorotine.Write()
gorotine.WG.Wait() //等待协程执行完
fmt.Println("ALL done !")

chan同步例子

package main

import (
"fmt"
)

func main() {
ch1 := make(chan int, 1)
ch2 := make(chan int, 1)
ch3 := make(chan int, 3)
go func() {
fmt.Println("1")
ch1 <- 1
}()
go func() {
<-ch1
fmt.Println("2")
ch2 <- 2
}()
go func() {
<-ch2
fmt.Println("3")
ch3 <- 3
}()
<-ch3
}

协程内主动交出控制权

runtime.Gosched()