網站首頁 編程語言 正文
創建協程
goroutine是go的設計核心,就是協程
主協程終止了,子協程也終止
package main import ( "fmt" "time" ) func newTask() { for { fmt.Println("this is a newTask") time.Sleep(time.Second) //延時1s } } func main() { go newTask() //新建一個協程, 新建一個任務 for { fmt.Println("this is a main goroutine") time.Sleep(time.Second) //延時1s } }
主協程終止,子協程也終止
package main import ( "fmt" "time" ) //主協程退出了,其它子協程也要跟著退出 func main() { go func() { i := 0 for { i++ fmt.Println("子協程 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時間片
等待其他協程執行完
runtime.Gosched()用于讓出CPU時間片,讓出當前goroutine(協程)的執行權限,調度器安排其他等待的任務運行,并在下次某個時候從該位置恢復執行。
類似:接力賽,A跑了一會碰到代碼runtime.Gosched()就把接力棒交給B,A歇著,B繼續跑
案例:
package main import ( "fmt" "runtime" ) func main() { go func() { for i := 0; i < 5; i++ { fmt.Println("go") } }() for i := 0; i < 2; i++ { //讓出時間片,先讓別的協議執行,它執行完,再回來執行此協程 runtime.Gosched() fmt.Println("hello") } } go go go go go hello hello
Goexit立即結束當前協程
runtime.Goexit() //立即結束當前協程
案例:
package main import ( "fmt" "runtime" ) func test() { defer fmt.Println("ccccccccccccc") //return //終止此函數 runtime.Goexit() //終止所在的協程 fmt.Println("dddddddddddddddddddddd") } func main() { //創建新建的協程 go func() { fmt.Println("aaaaaaaaaaaaaaaaaa") //調用了別的函數 test() fmt.Println("bbbbbbbbbbbbbbbbbbb") }() //別忘了() //特地寫一個死循環,目的不讓主協程結束 for { } } aaaaaaaaaaaaaaaaaa ccccccccccccc
GOMAXPROCS設置并行CPU核數最大值,并返回之前的值
runtime.GOMAXPROCS() //設置并行CPU核數最大值,并返回之前的值
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()獲取當前運行中的goroutine數量
先介紹一個最簡單的監控方式。
通過 runtime.NumGoroutine() 獲取當前運行中的 goroutine 數量,通過它確認是否發生泄漏。
func main() {
go test()
go test()
go test()
go test()
a:=runtime.NumGoroutine()
fmt.Println(a) // 5
for {
}
}
多任務資源競爭問題
package main import ( "fmt" "time" ) //定義一個打印機,參數為字符串,按每個字符打印 //打印機屬于公共資源 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個協程,代表2個人,2個人同時使用打印機 go person1() go person2() //特地不讓主協程結束,死循環 for { } }
通過channel解決資源競爭問題
package main import ( "fmt" "time" ) //全局變量,創建一個channel var ch = make(chan int) //定義一個打印機,參數為字符串,按每個字符打印 //打印機屬于公共資源 func Printer(str string) { for _, data := range str { fmt.Printf("%c", data) time.Sleep(time.Second) } fmt.Printf("\n") } //person1執行完后,才能到person2執行 func person1() { Printer("hello") ch <- 666 //給管道寫數據,發送 } func person2() { <-ch //從管道取數據,接收,如果通道沒有數據他就會阻塞 Printer("world") } func main() { //新建2個協程,代表2個人,2個人同時使用打印機 go person1() go person2() //特地不讓主協程結束,死循環 for { } }
主協程如何等其余協程完再退出
var wg sync.WaitGroup wg.Add(2) //任務數 wg.Done() //結束 wg.Wait() //等待 package main import ( "fmt" "sync" ) var wg sync.WaitGroup func main() { wg.Add(2) out := producer() consumer(out) defer fmt.Println("主線程結束") wg.Wait() //等待 } //此通道只能寫,不能讀 func producer() chan interface{} { ch := make(chan interface{}) go func() { for i := 0; i < 5; i++ { ch <- fmt.Sprintf("協程1-%d", i) //寫入字符串 } defer close(ch) wg.Done() //結束 }() return ch } //此channel只能讀,不能寫 func consumer(data chan interface{}) { defer fmt.Println("讀取結束") go func() { for num := range data { fmt.Println(num) } wg.Done() //結束 }() }
原文鏈接:https://www.cnblogs.com/guyouyin123/p/13985447.html
相關推薦
- 2022-05-12 Python 正則替換內容
- 2022-12-11 Django切換數據庫和遷移數據詳解_python
- 2022-05-13 C語言數據結構之二叉樹詳解_C 語言
- 2023-01-01 Pycharm沒有報錯提示(誤觸ignore)的完美解決方案_python
- 2022-09-13 Android?廣播接收器BroadcastReceiver詳解_Android
- 2022-08-26 詳解Python中元組的三個不常用特性_python
- 2022-06-07 進行數據處理的6個?Python?代碼塊分享_python
- 2022-07-11 Pandas常用累計、同比、環比等統計方法實踐過程_python
- 最近更新
-
- window11 系統安裝 yarn
- 超詳細win安裝深度學習環境2025年最新版(
- Linux 中運行的top命令 怎么退出?
- MySQL 中decimal 的用法? 存儲小
- get 、set 、toString 方法的使
- @Resource和 @Autowired注解
- Java基礎操作-- 運算符,流程控制 Flo
- 1. Int 和Integer 的區別,Jav
- spring @retryable不生效的一種
- Spring Security之認證信息的處理
- Spring Security之認證過濾器
- Spring Security概述快速入門
- Spring Security之配置體系
- 【SpringBoot】SpringCache
- Spring Security之基于方法配置權
- redisson分布式鎖中waittime的設
- maven:解決release錯誤:Artif
- restTemplate使用總結
- Spring Security之安全異常處理
- MybatisPlus優雅實現加密?
- Spring ioc容器與Bean的生命周期。
- 【探索SpringCloud】服務發現-Nac
- Spring Security之基于HttpR
- Redis 底層數據結構-簡單動態字符串(SD
- arthas操作spring被代理目標對象命令
- Spring中的單例模式應用詳解
- 聊聊消息隊列,發送消息的4種方式
- bootspring第三方資源配置管理
- GIT同步修改后的遠程分支