網(wǎng)站首頁 編程語言 正文
創(chuàng)建協(xié)程
goroutine是go的設(shè)計核心,就是協(xié)程
主協(xié)程終止了,子協(xié)程也終止
package main import ( "fmt" "time" ) func newTask() { for { fmt.Println("this is a newTask") time.Sleep(time.Second) //延時1s } } func main() { go newTask() //新建一個協(xié)程, 新建一個任務(wù) for { fmt.Println("this is a main goroutine") time.Sleep(time.Second) //延時1s } }
主協(xié)程終止,子協(xié)程也終止
package main import ( "fmt" "time" ) //主協(xié)程退出了,其它子協(xié)程也要跟著退出 func main() { go func() { i := 0 for { i++ fmt.Println("子協(xié)程 i = ", i) time.Sleep(time.Second) } }() //別忘了() i := 0 for { i++ fmt.Println("main i = ", i) time.Sleep(time.Second) if i == 2 { break } } }
runtime包
Gosched讓出CPU時間片
等待其他協(xié)程執(zhí)行完
runtime.Gosched()用于讓出CPU時間片,讓出當(dāng)前goroutine(協(xié)程)的執(zhí)行權(quán)限,調(diào)度器安排其他等待的任務(wù)運行,并在下次某個時候從該位置恢復(fù)執(zhí)行。
類似:接力賽,A跑了一會碰到代碼runtime.Gosched()就把接力棒交給B,A歇著,B繼續(xù)跑
案例:
package main import ( "fmt" "runtime" ) func main() { go func() { for i := 0; i < 5; i++ { fmt.Println("go") } }() for i := 0; i < 2; i++ { //讓出時間片,先讓別的協(xié)議執(zhí)行,它執(zhí)行完,再回來執(zhí)行此協(xié)程 runtime.Gosched() fmt.Println("hello") } } go go go go go hello hello
Goexit立即結(jié)束當(dāng)前協(xié)程
runtime.Goexit() //立即結(jié)束當(dāng)前協(xié)程
案例:
package main import ( "fmt" "runtime" ) func test() { defer fmt.Println("ccccccccccccc") //return //終止此函數(shù) runtime.Goexit() //終止所在的協(xié)程 fmt.Println("dddddddddddddddddddddd") } func main() { //創(chuàng)建新建的協(xié)程 go func() { fmt.Println("aaaaaaaaaaaaaaaaaa") //調(diào)用了別的函數(shù) test() fmt.Println("bbbbbbbbbbbbbbbbbbb") }() //別忘了() //特地寫一個死循環(huán),目的不讓主協(xié)程結(jié)束 for { } } aaaaaaaaaaaaaaaaaa ccccccccccccc
GOMAXPROCS設(shè)置并行CPU核數(shù)最大值,并返回之前的值
runtime.GOMAXPROCS() //設(shè)置并行CPU核數(shù)最大值,并返回之前的值
package main import ( "fmt" "runtime" ) func main() { //n := runtime.GOMAXPROCS(1) //指定以1核運算 n := runtime.GOMAXPROCS(2) //指定以8核運算 fmt.Println("n = ", n) for { go fmt.Print(1) fmt.Print(0) } }
runtime.NumGoroutine()獲取當(dāng)前運行中的goroutine數(shù)量
先介紹一個最簡單的監(jiān)控方式。
通過 runtime.NumGoroutine() 獲取當(dāng)前運行中的 goroutine 數(shù)量,通過它確認是否發(fā)生泄漏。
func main() {
go test()
go test()
go test()
go test()
a:=runtime.NumGoroutine()
fmt.Println(a) // 5
for {
}
}
多任務(wù)資源競爭問題
package main import ( "fmt" "time" ) //定義一個打印機,參數(shù)為字符串,按每個字符打印 //打印機屬于公共資源 func Printer(str string) { for _, data := range str { fmt.Printf("%c", data) time.Sleep(time.Second) } fmt.Printf("\n") } func person1() { Printer("hello") } func person2() { Printer("world") } func main() { //新建2個協(xié)程,代表2個人,2個人同時使用打印機 go person1() go person2() //特地不讓主協(xié)程結(jié)束,死循環(huán) for { } }
通過channel解決資源競爭問題
package main import ( "fmt" "time" ) //全局變量,創(chuàng)建一個channel var ch = make(chan int) //定義一個打印機,參數(shù)為字符串,按每個字符打印 //打印機屬于公共資源 func Printer(str string) { for _, data := range str { fmt.Printf("%c", data) time.Sleep(time.Second) } fmt.Printf("\n") } //person1執(zhí)行完后,才能到person2執(zhí)行 func person1() { Printer("hello") ch <- 666 //給管道寫數(shù)據(jù),發(fā)送 } func person2() { <-ch //從管道取數(shù)據(jù),接收,如果通道沒有數(shù)據(jù)他就會阻塞 Printer("world") } func main() { //新建2個協(xié)程,代表2個人,2個人同時使用打印機 go person1() go person2() //特地不讓主協(xié)程結(jié)束,死循環(huán) for { } }
主協(xié)程如何等其余協(xié)程完再退出
var wg sync.WaitGroup wg.Add(2) //任務(wù)數(shù) wg.Done() //結(jié)束 wg.Wait() //等待 package main import ( "fmt" "sync" ) var wg sync.WaitGroup func main() { wg.Add(2) out := producer() consumer(out) defer fmt.Println("主線程結(jié)束") wg.Wait() //等待 } //此通道只能寫,不能讀 func producer() chan interface{} { ch := make(chan interface{}) go func() { for i := 0; i < 5; i++ { ch <- fmt.Sprintf("協(xié)程1-%d", i) //寫入字符串 } defer close(ch) wg.Done() //結(jié)束 }() return ch } //此channel只能讀,不能寫 func consumer(data chan interface{}) { defer fmt.Println("讀取結(jié)束") go func() { for num := range data { fmt.Println(num) } wg.Done() //結(jié)束 }() }
原文鏈接:https://www.cnblogs.com/guyouyin123/p/13985447.html
相關(guān)推薦
- 2022-05-06 dyld[59644]: Library not loaded: /usr/local/opt/ic
- 2022-06-12 Go依賴注入DI工具wire使用詳解(golang常用庫包)_Golang
- 2022-04-17 WPF框架Prism中導(dǎo)航Navigation用法介紹_基礎(chǔ)應(yīng)用
- 2022-04-01 關(guān)于python中if __name=‘__main__‘的理解
- 2022-06-30 詳解Go語言中泛型的實現(xiàn)原理與使用_Golang
- 2022-11-28 如何將python代碼生成API接口_python
- 2022-01-17 MongoDB啟動失敗: 此應(yīng)用無法在你的電腦上運行
- 2021-12-02 如何解決用ESLint驗證導(dǎo)致報錯的問題
- 最近更新
-
- window11 系統(tǒng)安裝 yarn
- 超詳細win安裝深度學(xué)習(xí)環(huán)境2025年最新版(
- Linux 中運行的top命令 怎么退出?
- MySQL 中decimal 的用法? 存儲小
- get 、set 、toString 方法的使
- @Resource和 @Autowired注解
- Java基礎(chǔ)操作-- 運算符,流程控制 Flo
- 1. Int 和Integer 的區(qū)別,Jav
- spring @retryable不生效的一種
- Spring Security之認證信息的處理
- Spring Security之認證過濾器
- Spring Security概述快速入門
- Spring Security之配置體系
- 【SpringBoot】SpringCache
- Spring Security之基于方法配置權(quán)
- redisson分布式鎖中waittime的設(shè)
- maven:解決release錯誤:Artif
- restTemplate使用總結(jié)
- Spring Security之安全異常處理
- MybatisPlus優(yōu)雅實現(xiàn)加密?
- Spring ioc容器與Bean的生命周期。
- 【探索SpringCloud】服務(wù)發(fā)現(xiàn)-Nac
- Spring Security之基于HttpR
- Redis 底層數(shù)據(jù)結(jié)構(gòu)-簡單動態(tài)字符串(SD
- arthas操作spring被代理目標對象命令
- Spring中的單例模式應(yīng)用詳解
- 聊聊消息隊列,發(fā)送消息的4種方式
- bootspring第三方資源配置管理
- GIT同步修改后的遠程分支