并发
[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()