Golang - 并发编程
时间:2019-04-14 10:36:11
收藏:0
阅读:126
目录
Golang - 并发编程
1. 并行和并发
- 并行:在同一时刻,有多条指令在多个CPU处理器上同时执行
- 2个队伍,2个窗口,要求硬件支持
- 并发:在同一时刻,只能有一条指令执行,但多个进程指令被快速地轮换执行
- 2个队伍,1个窗口,要求提升软件能力
2. go语言并发优势
- go从语言层面就支持了并发
- 简化了并发程序的编写
3. goroutine是什么
- 它是go并发设计的核心
- goroutine就是协程,它比线程更小,十几个goroutine在底层可能就是五六个线程
- go语言内部实现了goroutine的内存共享,执行goroutine只需极少的栈内存(大概是4~5KB)
4. 创建goroutine
只需要在语句前添加go关键字,就可以创建并发执行单元
package main
import (
"fmt"
"time"
)//测试协程
//循环打印内容
func newTask() {
i := 0
for {
i++
fmt.Printf("new goroutine:i=%d\n", i)
time.Sleep(1 * time.Second)
}
}//main()相当于是主协程
func main() {
//启动子协程
go newTask()
i := 0
for {
i++
fmt.Printf("main goroutine:i=%d\n", i)
time.Sleep(1 * time.Second)
}
}- 开发?员无需了解任何执?细节,调度器会自动将其安排到合适的系统线程上执行
如果主协程退出了,其他任务还执行吗?不执行
package main import ( "fmt" "time" ) //main()相当于是主协程 func main() { //匿名子协程 go func() { i := 0 for { i++ fmt.Println("子协程 i=", i) time.Sleep(1 * time.Second) } }() i := 0 for { i++ fmt.Println("主协程 i=", i) time.Sleep(1 * time.Second) //主协程第二次后退出 if i == 2 { break } } }程序没任何输出,也不报错
package main import ( "fmt" "time" ) //main()相当于是主协程 func main() { //匿名子协程 go func() { i := 0 for { i++ fmt.Println("子协程 i=", i) time.Sleep(1 * time.Second) } }() }
5. runtime包
runtime.Gosched():用于让出CPU时间片,调度器重新安排任务调度,还是有几率分配到它的
package main import ( "fmt" "runtime" ) func main() { //匿名子协程 go func(s string) { for i := 0; i < 2; i++ { fmt.Println(s) } }("world") //主协程 for i := 0; i < 2; i++ { runtime.Gosched() fmt.Println("hello") } }runtime.Goexit():立即终止当前协程
package main import ( "fmt" "time" "runtime" ) func main() { //匿名子协程 go func() { defer fmt.Println("A.defer") //匿名函数 func() { defer fmt.Println("B.defer") //此时只有defer执行 runtime.Goexit() fmt.Println("B") }() fmt.Println("A") }() for { time.Sleep(time.Second) } }runtime.GOMAXPROCS():设置并行计算的CPU核数,返回之前的值
package main import ( "runtime" "fmt" ) func main() { n := runtime.GOMAXPROCS(3) fmt.Println("n=%d\n",n) //循环执行2个 for{ go fmt.Print(0) fmt.Print(1) } }
6. channel是什么
- goroutine运行在相同的地址空间,因此访问共享内存必须做好同步,处理好线程安全问题
- goroutine奉行通过通信来共享内存,而不是共享内存来通信
- channel是一个引用类型,用于多个goroutine通讯,其内部实现了同步,确保并发安全
7. channel的基本使用
- channel可以用内置make()函数创建
定义一个channel时,也需要定义发送到channel的值的类型
make(chan 类型) make(chan 类型, 容量)- 当 capacity= 0 时,channel 是无缓冲阻塞读写的,当capacity> 0 时,channel 有缓冲、是非阻塞的,直到写满 capacity个元素才阻塞写入
channel通过操作符<-来接收和发送数据,发送和接收数据语法:
channel <- value <-channel x := <-channel x, ok := <-channel
未完待续...
原文:https://www.cnblogs.com/konghui/p/10703615.html
评论(0)