在线不卡日本ⅴ一区v二区_精品一区二区中文字幕_天堂v在线视频_亚洲五月天婷婷中文网站

  • <menu id="lky3g"></menu>
  • <style id="lky3g"></style>
    <pre id="lky3g"><tt id="lky3g"></tt></pre>

    go并發(fā)編程

    協(xié)程(Goroutines)

    在Go語言中,每一個并發(fā)的執(zhí)行單元叫作一個goroutine。,我們只需要通過 go 關(guān)鍵字來開啟 goroutine 即可。goroutine 是輕量級線程,goroutine 的調(diào)度是由 Golang 運行時進行管理的。

    goroutine 語法格式:

    go 函數(shù)名( 參數(shù)列表 )

    示例

    package mainimport “fmt”func f(from string) {for i := 0; i < 3; i++ {fmt.Println(from, ":", i)}}func main() {// 假設(shè)我們有一個函數(shù)叫做 f(s)。// 我們使用一般的方式調(diào)并同時運行。f("direct")// 使用 go f(s) 在一個 Go 協(xié)程中調(diào)用這個函數(shù)。// 這個新的 Go 協(xié)程將會并行的執(zhí)行這個函數(shù)調(diào)用。go f("goroutine")// 你也可以為匿名函數(shù)啟動一個 Go 協(xié)程。go func(msg string) {fmt.Println(msg)}("going")// 現(xiàn)在這兩個 Go 協(xié)程在獨立的 Go 協(xié)程中異步的運行,所以我們需要等它們執(zhí)行結(jié)束。// 這里的 Scanln 代碼需要我們在程序退出前按下任意鍵結(jié)束。var input stringfmt.Scanln(&input)fmt.Println("done")// 當(dāng)我們運行這個程序時,將首先看到阻塞式調(diào)用的輸出,然后是兩個 Go 協(xié)程的交替輸出。// 這種交替的情況表示 Go 運行時是以異步的方式運行協(xié)程的。}

    通道(channel)

    如果說goroutine是Go語言程序的并發(fā)體的話,那么channels則是它們之間的通信機制。通道(channel)是用來傳遞數(shù)據(jù)的一個數(shù)據(jù)結(jié)構(gòu)。

    通道可用于兩個 goroutine 之間通過傳遞一個指定類型的值來同步運行和通訊。操作符 <- 用于指定通道的方向,發(fā)送或接收。如果未指定方向,則為雙向通道。

    ch <- v // 把 v 發(fā)送到通道 chv := <-ch // 從 ch 接收數(shù)據(jù) // 并把值賦給 v

    聲明一個通道很簡單,我們使用chan關(guān)鍵字即可,通道在使用前必須先創(chuàng)建:

    ch := make(chan int)

    示例:

    package mainimport (“fmt”)// 通道 是連接多個 Go 協(xié)程的管道。// 你可以從一個 Go 協(xié)程將值發(fā)送到通道,然后在別的 Go 協(xié)程中接收。func main() {// 使用 make(chan val-type) 創(chuàng)建一個新的通道。// 通道類型就是他們需要傳遞值的類型。messages := make(chan string)// 使用 channel <- 語法 發(fā)送 一個新的值到通道中。// 這里我們在一個新的 Go 協(xié)程中發(fā)送 "ping" 到上面創(chuàng)建的messages 通道中。go func() {messages <- "ping"}()// 使用 <-channel 語法從通道中 接收 一個值。// 這里將接收我們在上面發(fā)送的 "ping" 消息并打印出來。msg := <-messagesfmt.Println(msg)// 我們運行程序時,通過通道,消息 "ping" 成功的從一個 Go 協(xié)程傳到另一個中。// 默認(rèn)發(fā)送和接收操作是阻塞的,直到發(fā)送方和接收方都準(zhǔn)備完畢。// 這個特性允許我們,不使用任何其它的同步操作,來在程序結(jié)尾等待消息 "ping"。}

    通道緩沖區(qū)

    通道可以設(shè)置緩沖區(qū),通過 make 的第二個參數(shù)指定緩沖區(qū)大小:

    ch := make(chan int, 100)

    帶緩沖區(qū)的通道允許發(fā)送端的數(shù)據(jù)發(fā)送和接收端的數(shù)據(jù)獲取處于異步狀態(tài),就是說發(fā)送端發(fā)送的數(shù)據(jù)可以放在緩沖區(qū)里面,可以等待接收端去獲取數(shù)據(jù),而不是立刻需要接收端去獲取數(shù)據(jù)。

    不過由于緩沖區(qū)的大小是有限的,所以還是必須有接收端來接收數(shù)據(jù)的,否則緩沖區(qū)一滿,數(shù)據(jù)發(fā)送端就無法再發(fā)送數(shù)據(jù)了。

    注意:如果通道不帶緩沖,發(fā)送方會阻塞直到接收方從通道中接收了值。如果通道帶緩沖,發(fā)送方則會阻塞直到發(fā)送的值被拷貝到緩沖區(qū)內(nèi);如果緩沖區(qū)已滿,則意味著需要等待直到某個接收方獲取到一個值。接收方在有值可以接收之前會一直阻塞。

    示例:

    package mainimport “fmt”// 默認(rèn)通道是 無緩沖 的,這意味著只有在對應(yīng)的接收(<- chan)通道準(zhǔn)備好接收時,才允許進行發(fā)送(chan <-)。// 可緩存通道允許在沒有對應(yīng)接收方的情況下,緩存限定數(shù)量的值。func main() {// 這里我們 make 了一個通道,最多允許緩存 2 個值。messages := make(chan string, 2)// 因為這個通道是有緩沖區(qū)的,即使沒有一個對應(yīng)的并發(fā)接收方,我們?nèi)匀豢梢园l(fā)送這些值。messages <- "buffered"messages <- "channel"// 然后我們可以像前面一樣接收這兩個值。fmt.Println(<-messages)fmt.Println(<-messages)}

    同步實現(xiàn)

    我們可以通過channel實現(xiàn)同步,如下:

    package mainimport “fmt”import “time”// 我們可以使用通道來同步 Go 協(xié)程間的執(zhí)行狀態(tài)。// 這里是一個使用阻塞的接受方式來等待一個 Go 協(xié)程的運行結(jié)束。func worker(done chan bool) {// 這是一個我們將要在 Go 協(xié)程中運行的函數(shù)。// done 通道將被用于通知其他 Go 協(xié)程這個函數(shù)已經(jīng)工作完畢。fmt.Print(“working…”)time.Sleep(time.Second)fmt.Println(“done”)// 發(fā)送一個值來通知我們已經(jīng)完工啦。done <- true}func main() {// 運行一個 worker Go協(xié)程,并給予用于通知的通道。done := make(chan bool, 1)go worker(done)// 程序?qū)⒃诮邮盏酵ǖ乐?worker 發(fā)出的通知前一直阻塞。<-done// 如果你把 <- done 這行代碼從程序中移除,程序甚至?xí)?worker還沒開始運行時就結(jié)束了。}

    通道方向示例

    package mainimport “fmt”// 當(dāng)使用通道作為函數(shù)的參數(shù)時,你可以指定這個通道是不是只用來發(fā)送或者接收值。// 這個特性提升了程序的類型安全性。func ping(pings chan <- string, msg string) {// ping 函數(shù)定義了一個只允許發(fā)送數(shù)據(jù)的通道。// 嘗試使用這個通道來接收數(shù)據(jù)將會得到一個編譯時錯誤。pings <- msg}func pong(pings <-chan string, pongs chan <- string) {// pong 函數(shù)允許通道(pings)來接收數(shù)據(jù),另一通道(pongs)來發(fā)送數(shù)據(jù)。msg := <-pingspongs <- msg}func main() {pings := make(chan string, 1)pongs := make(chan string, 1)ping(pings, "passed message")pong(pings, pongs)fmt.Println(<-pongs)}

    Go 遍歷通道與關(guān)閉通道

    Go 通過 range 關(guān)鍵字來實現(xiàn)遍歷讀取到的數(shù)據(jù),類似于與數(shù)組或切片。格式如下:

    v, ok := <-ch

    如果通道接收不到數(shù)據(jù)后 ok 就為 false,這時通道就可以使用 close() 函數(shù)來關(guān)閉。

    通道選擇器(select)

    select {case <-ch1: // …case x := <-ch2: // …use x…case ch3 <- y: // …default: // …}

    select語句的一般形式。和switch語句稍微有點相似,也會有幾個case和最后的default選擇支。每一個case代表一個通信操作(在某個channel上進行發(fā)送或者接收)并且會包含一些語句組成的一個語句塊。一個接收表達(dá)式可能只包含接收表達(dá)式自身(譯注:不把接收到的值賦值給變量什么的),就像上面的第一個case,或者包含在一個簡短的變量聲明中,像第二個case里一樣;第二種形式讓你能夠引用接收到的值。

    select會等待case中有能夠執(zhí)行的case時去執(zhí)行。當(dāng)條件滿足時,select才會去通信并執(zhí)行case之后的語句;這時候其它通信是不會執(zhí)行的。一個沒有任何case的select語句寫作select{},會永遠(yuǎn)地等待下去。

    示例:

    package mainimport “time”import “fmt”// Go 的通道選擇器 讓你可以同時等待多個通道操作。// Go 協(xié)程和通道以及選擇器的結(jié)合是 Go 的一個強大特性。func main() {// 在我們的例子中,我們將從兩個通道中選擇。c1 := make(chan string)c2 := make(chan string)// 各個通道將在若干時間后接收一個值,這個用來模擬例如并行的 Go 協(xié)程中阻塞的 RPC 操作go func() {time.Sleep(time.Second * 1)c1 <- "one"}()go func() {time.Sleep(time.Second * 2)c2 <- "two"}()// 我們使用 select 關(guān)鍵字來同時等待這兩個值,并打印各自接收到的值。for i := 0; i < 2; i++ {select {case msg1 := <-c1:fmt.Println("received", msg1)case msg2 := <-c2:fmt.Println("received", msg2)}}// 我們首先接收到值 "one",然后就是預(yù)料中的 "two"了。// 注意從第一次和第二次 Sleeps 并發(fā)執(zhí)行,總共僅運行了兩秒左右。}

    超時實現(xiàn)

    package mainimport “time”import “fmt”// 超時 對于一個連接外部資源,或者其它一些需要花費執(zhí)行時間的操作的程序而言是很重要的。// 得益于通道和 select,在 Go中實現(xiàn)超時操作是簡潔而優(yōu)雅的。func main() {c1 := make(chan string, 1)// 在我們的例子中,假如我們執(zhí)行一個外部調(diào)用,并在 2 秒后通過通道 c1 返回它的執(zhí)行結(jié)果。go func() {time.Sleep(time.Second * 2)c1 <- "result 1"}()// 這里是使用 select 實現(xiàn)一個超時操作。res := <- c1 等待結(jié)果,<-Time.After 等待超時時間 1 秒后發(fā)送的值。// 由于 select 默認(rèn)處理第一個已準(zhǔn)備好的接收操作,如果這個操作超過了允許的 1 秒的話,將會執(zhí)行超時 case。select {case res := <-c1:fmt.Println(res)case <-time.After(time.Second * 1):fmt.Println("timeout 1")}// 如果我允許一個長一點的超時時間 3 秒,將會成功的從 c2接收到值,并且打印出結(jié)果。c2 := make(chan string, 1)go func() {time.Sleep(time.Second * 2)c2 <- "result 2"}()select {case res := <-c2:fmt.Println(res)case <-time.After(time.Second * 3):fmt.Println("timeout 2")}// 運行這個程序,首先顯示運行超時的操作,然后是成功接收的。// 使用這個 select 超時方式,需要使用通道傳遞結(jié)果。// 這對于一般情況是個好的方式,因為其他重要的 Go 特性是基于通道和select 的。}

    非阻塞選擇器

    package mainimport (“fmt”)// 常規(guī)的通過通道發(fā)送和接收數(shù)據(jù)是阻塞的。// 然而,我們可以使用帶一個 default 子句的 select 來實現(xiàn)非阻塞 的發(fā)送、接收,甚至是非阻塞的多路 select。func main() {messages := make(chan string)signals := make(chan bool)// 這里是一個非阻塞接收的例子。// 如果在 messages 中存在,然后 select 將這個值帶入 <-messages case中。// 如果不是,就直接到 default 分支中。select {case msg := <-messages:fmt.Println("received message", msg)default:fmt.Println("no message received")}// 一個非阻塞發(fā)送的實現(xiàn)方法和上面一樣。msg := "hi"select {case messages <- msg:fmt.Println("sent message", msg)default:fmt.Println("no message sent")}// 我們可以在 default 前使用多個 case 子句來實現(xiàn)一個多路的非阻塞的選擇器。// 這里我們試圖在 messages和 signals 上同時使用非阻塞的接受操作。select {case msg := <-messages:fmt.Println("received message", msg)case sig := <-signals:fmt.Println("received signal", sig)default:fmt.Println("no activity")}}

    分享不易~ 感謝大家閱讀

    鄭重聲明:本文內(nèi)容及圖片均整理自互聯(lián)網(wǎng),不代表本站立場,版權(quán)歸原作者所有,如有侵權(quán)請聯(lián)系管理員(admin#wlmqw.com)刪除。
    用戶投稿
    上一篇 2022年6月21日 06:29
    下一篇 2022年6月21日 06:29

    相關(guān)推薦

    • 存儲過程語法(sql server存儲過程語法)

      今天小編給各位分享存儲過程語法的知識,其中也會對sql server存儲過程語法進行解釋,如果能碰巧解決你現(xiàn)在面臨的問題,別忘了關(guān)注本站,現(xiàn)在開始吧! oracle存儲過程基本語法…

      2022年11月26日
    • 《寶可夢朱紫》獒教父屬性是什么?獒教父屬性一覽

      寶可夢朱紫里獒教父是一只很強的寶可夢,很多玩家不清楚獒教父的屬性是什么樣的,下面就給大家?guī)韺毧蓧糁熳祥峤谈笇傩砸挥[,感興趣的小伙伴一起來看看吧,希望能幫助到大家。 獒教父屬性一覽…

      2022年11月25日
    • 《寶可夢朱紫》夢特性怎么獲得?隱藏特性獲取方法推薦

      寶可夢朱紫里有很多寶可夢都是擁有夢特性會變強的寶可夢,很多玩家不知道夢特性怎么獲得,下面就給大家?guī)韺毧蓧糁熳想[藏特性獲取方法推薦,感興趣的小伙伴一起來看看吧,希望能幫助到大家。 …

      2022年11月25日
    • 什么是推廣cpa一篇文章帶你看懂CPA推廣渠道

      CPA渠道 CPA指的是按照指定的行為結(jié)算,可以是搜索,可以是注冊,可以是激活,可以是搜索下載激活,可以是綁卡,實名認(rèn)證,可以是付費,可以是瀏覽等等。甲乙雙方可以根據(jù)自己的情況來定…

      2022年11月25日
    • 抖音直播帶貨有哪些方法技巧(抖音直播帶貨有哪些痛點)

      如今抖音這個短視頻的變現(xiàn)能力越來越突顯了,尤其是在平臺上開通直播,更具有超強的帶貨屬性,已經(jīng)有越來越多的普通人加入到其中了。不過直播帶貨雖然很火,但是也不是每個人都能做好的,那么在…

      2022年11月24日
    • 淘寶直播平臺抽成多少(淘寶直播平臺抽成比例)

      隨著時代的發(fā)展,現(xiàn)在直播帶貨已經(jīng)成為主要帶貨方式,其中淘寶是主流帶貨平臺,不少人在上面直播帶貨賺錢,一些小伙伴也想加入,那么淘寶直播平臺抽成多少?下面小編為大家?guī)硖詫氈辈テ脚_抽成…

      2022年11月24日
    • 淘寶直播開通后帶貨鏈接怎么做(淘寶直播需要開通淘寶店鋪嗎)

      直播帶貨無論是對于商家來說還是主播收益都是非??捎^的,所以不少平臺都有直播帶貨功能,一些小伙伴也想加入淘寶直播,那么淘寶直播開通后帶貨鏈接怎么做?下面小編為大家?guī)硖詫氈辈ラ_通后帶…

      2022年11月24日
    • 今天出入濟南最新通知(出入濟南政策最新消息今天)

      近日濟南疫情感染人數(shù)也在不斷增加,劃分的高風(fēng)險區(qū)也是越來越多了。據(jù)最新統(tǒng)計,截止2022年11月24日11時,濟南共有低風(fēng)險地區(qū)12處,高風(fēng)險地區(qū)338處。很多朋友都擔(dān)心現(xiàn)在濟南無…

      2022年11月24日
    • 白襯衫搭配什么褲子好看,女生襯衫穿法圖片

      說起白襯衫和長褲的搭配組合,不知道大家有沒有發(fā)現(xiàn),雖然是很常見的造型,可不同年齡段慣用的穿搭方式卻不相同,從而也穿出了不同的味道。簡直是現(xiàn)在這個季節(jié),時髦精們的必備造型之一~ 70…

      2022年11月24日
    • 明查|美國新冠后遺癥患者中有16%癥狀嚴(yán)重以致無法工作?

      點擊進入澎湃新聞全球事實核查平臺 速覽 – 網(wǎng)傳數(shù)據(jù)比例無權(quán)威信源佐證,該比例有可能是結(jié)合了美國疾病防控中心和布魯金斯學(xué)會的數(shù)據(jù)得出,但這兩個機構(gòu)的調(diào)研目的和樣本都不同…

      2022年11月24日

    聯(lián)系我們

    聯(lián)系郵箱:admin#wlmqw.com
    工作時間:周一至周五,10:30-18:30,節(jié)假日休息