目录
-
Golang - 并发编程
- 1. 并行和并发
- 2. go语言并发优势
- 3. goroutine是什么
- 4. 创建goroutine
- 5. runtime包
- 6. channel是什么
- 7. channel的基本使用
Golang - 并发编程
1. 并行和并发
- 并行:在同一时刻,有多条指令在多个CPU处理器上同时执行
- 2个队伍,2个窗口,要求硬件支持
- 并发:在同一时刻,只能有一条指令执行,但多个进程指令被快速地轮换执行
- 2个队伍,1个窗口,要求提升软件能力
2. 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=%dn",i) time.Sleep(1 * time.Second) } } //main()相当于是主协程 func main() { //启动子协程 go newTask() i := 0 for { i++ fmt.Printf("main goroutine:i=%dn",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=%dn",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
未完待续...
(编辑:李大同)
【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!
|