最美情侣中文字幕电影,在线麻豆精品传媒,在线网站高清黄,久久黄色视频

歡迎光臨散文網(wǎng) 會(huì)員登陸 & 注冊(cè)

Go 并發(fā)

2023-03-15 18:11 作者:是愛(ài)你的君君呀  | 我要投稿

Go?語(yǔ)言支持并發(fā),我們只需要通過(guò)?go?關(guān)鍵字來(lái)開(kāi)啟?goroutine?即可。

goroutine?是輕量級(jí)線程,goroutine?的調(diào)度是由?Golang?運(yùn)行時(shí)進(jìn)行管理的。

goroutine?語(yǔ)法格式:

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

例如:

go?f(x,?y,?z)

開(kāi)啟一個(gè)新的?goroutine:

f(x,?y,?z)

Go?允許使用?go?語(yǔ)句開(kāi)啟一個(gè)新的運(yùn)行期線程,?即?goroutine,以一個(gè)不同的、新創(chuàng)建的?goroutine?來(lái)執(zhí)行一個(gè)函數(shù)。?同一個(gè)程序中的所有?goroutine?共享同一個(gè)地址空間。

實(shí)例

package?main

import?(
"fmt"
"time"
)

func?say(s?string)?{
for?i?:=?0;?i?<?5;?i++?{
time.Sleep(100?*?time.Millisecond)
fmt.Println(s)
}
}

func?main()?{
go?say("world")
say("hello")
}

執(zhí)行以上代碼,你會(huì)看到輸出的?hello?和?world?是沒(méi)有固定先后順序。因?yàn)樗鼈兪莾蓚€(gè)?goroutine?在執(zhí)行:

worldhellohelloworldworldhellohelloworldworldhello

通道(channel)

通道(channel)是用來(lái)傳遞數(shù)據(jù)的一個(gè)數(shù)據(jù)結(jié)構(gòu)。

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

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

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

ch?:=?make(chanint)

注意:默認(rèn)情況下,通道是不帶緩沖區(qū)的。發(fā)送端發(fā)送數(shù)據(jù),同時(shí)必須有接收端相應(yīng)的接收數(shù)據(jù)。

以下實(shí)例通過(guò)兩個(gè)?goroutine?來(lái)計(jì)算數(shù)字之和,在?goroutine?完成計(jì)算后,它會(huì)計(jì)算兩個(gè)結(jié)果的和:

實(shí)例

package?main

import?"fmt"

func?sum(s?[]int,?c?chan?int)?{
sum?:=?0
for?_,?v?:=?range?s?{
sum?+=?v
}
c?<-?sum?//?把?sum?發(fā)送到通道?c
}

func?main()?{
s?:=?[]int{7,?2,?8,?-9,?4,?0}

c?:=?make(chan?int)
go?sum(s[:len(s)/2],?c)
go?sum(s[len(s)/2:],?c)
x,?y?:=?<-c,?<-c?//?從通道?c?中接收

fmt.Println(x,?y,?x+y)
}

輸出結(jié)果為:

-5?17?12

通道緩沖區(qū)

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

ch?:=?make(chanint,?100)

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

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

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

實(shí)例

package?main

import?"fmt"

func?main()?{
//?這里我們定義了一個(gè)可以存儲(chǔ)整數(shù)類(lèi)型的帶緩沖通道
//?緩沖區(qū)大小為2
ch?:=?make(chan?int,?2)

//?因?yàn)?ch?是帶緩沖的通道,我們可以同時(shí)發(fā)送兩個(gè)數(shù)據(jù)
//?而不用立刻需要去同步讀取數(shù)據(jù)
ch?<-?1
ch?<-?2

//?獲取這兩個(gè)數(shù)據(jù)
fmt.Println(<-ch)
fmt.Println(<-ch)
}

執(zhí)行輸出結(jié)果為:

12

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

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

v,?ok?:=?<-ch

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

實(shí)例

package?main

import?(
"fmt"
)

func?fibonacci(n?int,?c?chan?int)?{
x,?y?:=?0,?1
for?i?:=?0;?i?<?n;?i++?{
c?<-?x
x,?y?=?y,?x+y
}
close(c)
}

func?main()?{
c?:=?make(chan?int,?10)
go?fibonacci(cap(c),?c)
//?range?函數(shù)遍歷每個(gè)從通道接收到的數(shù)據(jù),因?yàn)?c?在發(fā)送完?10?個(gè)
//?數(shù)據(jù)之后就關(guān)閉了通道,所以這里我們?range?函數(shù)在接收到?10?個(gè)數(shù)據(jù)
//?之后就結(jié)束了。如果上面的?c?通道不關(guān)閉,那么?range?函數(shù)就不
//?會(huì)結(jié)束,從而在接收第?11?個(gè)數(shù)據(jù)的時(shí)候就阻塞了。
for?i?:=?range?c?{
fmt.Println(i)
}
}

執(zhí)行輸出結(jié)果為:

0112358132134



Go 并發(fā)的評(píng)論 (共 條)

分享到微博請(qǐng)遵守國(guó)家法律
微山县| 临清市| 天台县| 永安市| 梧州市| 绥德县| 南江县| 电白县| 乐陵市| 鄂伦春自治旗| 桃江县| 布尔津县| 普安县| 内黄县| 吉林省| 太康县| 长治市| 仲巴县| 鹰潭市| 高尔夫| 增城市| 肇东市| 汉源县| 白山市| 泸州市| 巢湖市| 甘肃省| 武义县| 泽库县| 鞍山市| 邵东县| 和田县| 潜山县| 开阳县| 高邑县| 上栗县| 渝北区| 乐都县| 澎湖县| 康保县| 仪征市|