Go 协程
2024-10-20 11:51:42
Go 协程
协程与传统的系统级线程和进程相比,协程的优势在于其"轻量级",可以轻松创建上百万个协程而不会导致系统资源衰竭,所以协程也叫做轻量级线程。
在Go中goroutine就是协程的意思,不同的是,Go在runtime、系统调用等多方面对goroutine调度进行了封装和处理,当遇到长时间执行或者进行系统调用时,会主动把当前goroutine的CPU转让出去,让其他goroutine能被调度并执行。
在Go中应用协程
在Go中应用协程,只需要在一个函数调用前加入go关键字,就可以实现协程,如:
package main
import "fmt"
func Add(x,y int){
z := x + y
fmt.Println(z)
}
func main(){
for i:=0;i<10;i++{
go Add(i, i)
}
}
运行程序会发现没有任何输出,因为程序运行主函数很快就退出了,没有机会去执行Add函数中输出语句,所以我们在主函数中加一点延时
package main
import (
"fmt"
"time"
)
func Add(x,y int){
z := x + y
fmt.Println(z)
}
func main(){
for i:=0;i<10;i++{
go Add(i, i)
}
time.Sleep(time.Second)
}
这里我们就可以看到输出了
4
0
12
6
8
10
16
14
18
2
协程同步
下面的例子使用锁来实现协程同步,但是Go提供了更好的方式实现协程同步。
没有加锁的案例:
func Show(str string){
for _, i := range str{
fmt.Printf("%c", i)
time.Sleep(time.Second)
}
}
func main(){
go Show("hello")
go Show("world")
// 死循环不让主函数退出,和Sleep效果一致
for {
fmt.Print()
}
}
输出结果:
hwoelrlldo
这并不是我们想要的效果,所以加上锁,案例:
func Show(str string, lock *sync.Mutex){
lock.Lock()
for _, i := range str{
fmt.Printf("%c", i)
time.Sleep(time.Second)
}
lock.Unlock()
}
func main(){
lock := &sync.Mutex{}
go Show("hello", lock)
go Show("world", lock)
// 死循环不让主函数退出,和Sleep效果一致
for {
fmt.Print()
}
}
加上锁之后,输出的结果:
helloworld
这就达到了协程同步的效果。当然还有更好的方式,channel。
最新文章
- ABP源码分析四十六:ABP ZERO中的Ldap模块
- Windows Live Writer体验
- iBatis简单入门教程
- JavaBean学习总结(上)
- SQL语言基础
- themepark模板中奇特的编码
- Android闹钟开发与展示Demo
- mysql 存储过程和存储函数
- MYSQL数据库操作语句
- 【linux】三十分钟学会AWK
- 让阿里云支持ipv6(其他多数VPS通用)
- 谈谈.NET中常见的内存泄露问题——GC、委托事件和弱引用
- 1.1 java学习网站
- Block 朴实理解
- Sublime text3插件安装方法
- Delaunay triangulation
- Codeforces Round #514 (Div. 2)
- Android开发中常见的设计模式(一)——单例模式
- Django 序列化三种方式 对象 列表 元组
- How to Set Up DTrace to Detect PHP Scripting Problems on Oracle Linux
热门文章
- rust-vmm 学习
- 【UVA11134】传说中的车
- 解决Git - git push origin master 报错
- SpringBoot:关于默认连接池Hikari的源码剖析
- 利用chocolate包管理工具安装helm
- QString 中文编码转换
- c#修改webservice 的地址和端口(修改配置文件)
- Java面试底层原理
- 【SpringBoot】SpringBoot快速入门(一)
- php composer 报错 requires php ^7.1.8 || ^8.0 ->; your php version