日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當(dāng)前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

go 协程

發(fā)布時間:2024/8/1 编程问答 36 豆豆
生活随笔 收集整理的這篇文章主要介紹了 go 协程 小編覺得挺不錯的,現(xiàn)在分享給大家,幫大家做個參考.

概述

? ? ? ? ??Go協(xié)程(Goroutine)是與其他函數(shù)或方法同時運(yùn)行的函數(shù)或方法。可以認(rèn)為Go協(xié)程是輕量級的線程。與創(chuàng)建線程相比,創(chuàng)建Go協(xié)程的成本很小。因此在Go中同時運(yùn)行上千個協(xié)程是很常見的。

?

Go協(xié)程對比線程的優(yōu)點

  • 與線程相比,Go協(xié)程的開銷非常小。Go協(xié)程的堆棧大小只有幾kb,它可以根據(jù)應(yīng)用程序的需要而增長和縮小,而線程必須指定堆棧的大小,并且堆棧的大小是固定的。

  • Go協(xié)程被多路復(fù)用到較少的OS線程。在一個程序中數(shù)千個Go協(xié)程可能只運(yùn)行在一個線程中。如果該線程中的任何一個Go協(xié)程阻塞(比如等待用戶輸入),那么Go會創(chuàng)建一個新的OS線程并將其余的Go協(xié)程移動到這個新的OS線程。所有這些操作都是 runtime 來完成的,而我們程序員不必關(guān)心這些復(fù)雜的細(xì)節(jié),只需要利用 Go 提供的簡潔的 API 來處理并發(fā)就可以了。

  • Go 協(xié)程之間通過信道(channel)進(jìn)行通信。信道可以防止多個協(xié)程訪問共享內(nèi)存時發(fā)生竟險(race condition)。信道可以想象成多個協(xié)程之間通信的管道。

goroutine 可能切換的點

  • 非強(qiáng)占式

  • I/O ,select

  • channel

  • 等待鎖

  • 調(diào)用函數(shù)

  • runtime.Gosched()

  • 只是參考,不能保證切換

代碼一

package mainimport ("fmt""time" )func sample(message chan string) {message <- "hello goroutine!1"message <- "hello goroutine!2"message <- "hello goroutine!3"message <- "hello goroutine!4" }func sampleTwo(message chan string) {time.Sleep(2 * time.Second)str := <-messagestr = str + "I am goroutinetwo"message <- strclose(message) }func main() {/*** 隊列為3的*/var message = make(chan string, 3)go sample(message)go sampleTwo(message)time.Sleep(3 * time.Second)str := <-messagefmt.Println(str)fmt.Println(<-message)for strTemp := range message {fmt.Println(strTemp)}}

代碼二

? ??select 多個隊列的隨機(jī)選擇

package mainimport ("strconv""time""fmt" )func sample(ch chan string) {for i := 0; i < 19; i++ {ch <- "I am sample num :" + strconv.Itoa(i)time.Sleep(1 * time.Second)} }func sampleTwo(ch chan int) {for i := 0; i < 10; i++ {ch <- itime.Sleep(2 * time.Second)} }func main() {/*** 隊列為3的*/var ch1 = make(chan string, 3)var ch2 = make(chan int, 5)for i := 0; i < 10; i++ {go sample(ch1)go sampleTwo(ch2)}// select 多個隊列的隨機(jī)選擇for i := 0; i < 1000; i++ {select {case str, ch1Check := <-ch1:if !ch1Check {fmt.Println("ch1Check false")}fmt.Println(str)case p, ch2Check := <-ch2:if !ch2Check {fmt.Println("ch2Check false")}fmt.Println(p)}}time.Sleep(60 * time.Second) }

加大兩個sample的時間差

?

package mainimport ("strconv""time""fmt" )func sample(ch chan string) {for i := 0; i < 19; i++ {ch <- "I am sample num :" + strconv.Itoa(i)time.Sleep(3 * time.Second)} }func sampleTwo(ch chan int) {for i := 0; i < 10; i++ {ch <- itime.Sleep(60 * time.Second)} }func main() {/*** 隊列為3的*/var ch1 = make(chan string, 3)var ch2 = make(chan int, 5)for i := 0; i < 10; i++ {go sample(ch1)go sampleTwo(ch2)}// select 多個隊列的隨機(jī)選擇for {select {case str, ch1Check := <-ch1:if !ch1Check {fmt.Println("ch1Check false")}fmt.Println(str)case p, ch2Check := <-ch2:if !ch2Check {fmt.Println("ch2Check false")}fmt.Println(p)}}}

參考:

https://www.yuque.com/docs/share/999e271e-2418-44c9-a9ff-8fc30aef8e96

總結(jié)

以上是生活随笔為你收集整理的go 协程的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網(wǎng)站內(nèi)容還不錯,歡迎將生活随笔推薦給好友。