标签:port 线程安全 共享 highlight goroutine range 取数据 实现 直接
goroutine的使用
//Learn_Go/main.go package main import ( "fmt" "time" ) func demo(count int) { for i :=1; i < 10; i++{ fmt.Println(count,":",i) } } func main() { for i :=1; i < 10; i++{ go demo(i) } //添加休眠时间等待goroutine执行结束 time.Sleep(3e9) }
WaitGroup直译为等待组,其实就是计数器,只要计数器中有内容将一直阻塞
WaitGroup有三种方法
//Learn_Go/main.go package main import ( "fmt" "sync" ) func main() { var wg sync.WaitGroup wg.Add(5) for i := 0; i < 5; i++{ go func(j int) { fmt.Println("第",j,"次执行") wg.Done() }(i) } wg.Wait() fmt.Println("程序结束") }
(1)互斥锁
可以使用sync.Mutex对内容加锁,互斥锁的使用场景
(2)读写锁
Go语言中的map不是线程安全的,多个gouroutine同时操作会出现错误
RWMutex可以添加多个读锁或者一个写锁,读写锁不能同时存在
map在并发下读写就需要结合读写锁完成
互斥锁表示锁的代码同一时间只能有一个goroutine运行,而读写锁表示在锁范围内数据的读写操作
//Learn_Go/main.go package main import ( "fmt" "sync" ) func main() { var rwm sync.RWMutex var wg sync.WaitGroup wg.Add(10) m := make(map[int]int) for i := 0; i < 10; i++{ go func(j int) { rwm.Lock() m[j] = j fmt.Println(m) rwm.Unlock() wg.Done() }(i) } wg.Wait() fmt.Println("程序结束") }
channel是进程内通信方式,每个channel只能传递一个类型的值,这个类型需要在声明channel时指定
channel在Go中主要的两个作用:同步和通信
(1)声明channel的语法
(2)操作channel的语法
(3)无论是向channel存数据还是取数据都会阻塞
//Learn_Go/main.go package main import "fmt" func main() { ch := make(chan int) go func() { fmt.Println("执行") ch <- 111 }() a := <- ch fmt.Println(a) fmt.Println("程序结束") }
(4)使用channel实现gouroutine之间通信
//Learn_Go/main.go package main import "fmt" func main() { ch1 := make(chan string) ch2 := make(chan int) go func() { ch1 <- "derek" ch2 <- 111 }() go func() { content := <- ch1 fmt.Println("取出数据:",content) //取出数据: derek ch2 <- 222 }() a := <- ch2 b := <- ch2 fmt.Println(a,b) //111 222 fmt.Println("程序结束") }
(5)可以使用for range获取channel中内容
//Learn_Go/main.go package main import "fmt" func main() { ch1 := make(chan int) ch2 := make(chan int) go func() { for i := 0; i<10;i++{ ch1 <- i } ch2 <- 222 }() go func() { for n := range ch1{ fmt.Println(n) } }() <- ch2 fmt.Println("程序结束") }
select执行过程
//Learn_Go/main.go package main import "fmt" func main() { ch1 := make(chan int,2) //有缓存的channel ch2 := make(chan int,3) ch1 <- 111 ch2 <- 222 select { case a := <-ch1: fmt.Println(a) case b := <-ch2: fmt.Println(b) default: fmt.Println("错误") } }
select多和for循环结合使用
//Learn_Go/main.go package main import "fmt" func main() { ch := make(chan int) for i := 0; i < 10;i++{ go func(j int) { ch <- j }(i) } //用for循环一直接受 for { select { case a := <- ch: fmt.Println(a) default: } } }
10.Go-goroutine,waitgroup,互斥锁,channel和select
标签:port 线程安全 共享 highlight goroutine range 取数据 实现 直接
原文地址:https://www.cnblogs.com/derek1184405959/p/11333376.html