最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

淺談golang for 循環(huán)中使用協(xié)程的問(wèn)題

 更新時(shí)間:2020年12月21日 14:17:53   作者:胖達(dá)團(tuán)長(zhǎng)  
這篇文章主要介紹了淺談golang for 循環(huán)中使用協(xié)程的問(wèn)題,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過(guò)來(lái)看看吧

兩個(gè)例子

package main 
import (
 "fmt"
 "time"
)
 
func Process1(tasks []string) {
 for _, task := range tasks {
 // 啟動(dòng)協(xié)程并發(fā)處理任務(wù)
 go func() {
 fmt.Printf("Worker start process task: %s\n", task)
 }()
 }
}
 
func main() { 
 tasks := []string{"1", "2", "3", "4", "5"}
 Process1(tasks)
 time.Sleep(2 * time.Second)
}

結(jié)果:

第一次運(yùn)行

Worker start process task: 3
Worker start process task: 4
Worker start process task: 4
Worker start process task: 5
Worker start process task: 5

第二次運(yùn)行

Worker start process task: 2
Worker start process task: 5
Worker start process task: 5
Worker start process task: 5
Worker start process task: 5
package main 
import (
 "fmt"
 "time"
)
 
func Process1(tasks []string) {
 for _, task := range tasks {
 // 啟動(dòng)協(xié)程并發(fā)處理任務(wù)
 go func() {
 fmt.Printf("Worker start process task: %s\n", task)
 }()
 }
}
 
func Process2(tasks []string) {
 for _, task := range tasks {
 // 啟動(dòng)協(xié)程并發(fā)處理任務(wù)
 go func(t string) {
 fmt.Printf("Worker start process task: %s\n", t)
 }(task)
 }
}
func main() {
 tasks := []string{"1", "2", "3", "4", "5"}
 Process2(tasks)
 time.Sleep(2 * time.Second)
}

結(jié)果

第一次運(yùn)行

Worker start process task: 5
Worker start process task: 4
Worker start process task: 2
Worker start process task: 3
Worker start process task: 1

第二次運(yùn)行

Worker start process task: 2
Worker start process task: 5
Worker start process task: 4
Worker start process task: 1
Worker start process task: 3

上述問(wèn)題,有個(gè)共同點(diǎn)就是都引用了循環(huán)變量。即在for index, value := range xxx語(yǔ)句中,

index和value便是循環(huán)變量。不同點(diǎn)是循環(huán)變量的使用方式,有的是直接在協(xié)程中引用(題目一),有的作為參數(shù)傳遞(題目二)。

循環(huán)變量是易變的

首先,循環(huán)變量實(shí)際上只是一個(gè)普通的變量。

語(yǔ)句for index, value := range xxx中,每次循環(huán)index和value都會(huì)被重新賦值(并非生成新的變量)。

如果循環(huán)體中會(huì)啟動(dòng)協(xié)程(并且協(xié)程會(huì)使用循環(huán)變量),就需要格外注意了,因?yàn)楹芸赡苎h(huán)結(jié)束后協(xié)程才開(kāi)始執(zhí)行,

此時(shí),所有協(xié)程使用的循環(huán)變量有可能已被改寫(xiě)。(是否會(huì)改寫(xiě)取決于引用循環(huán)變量的方式)

循環(huán)變量需要綁定

在題目一中,協(xié)程函數(shù)體中引用了循環(huán)變量task,協(xié)程從被創(chuàng)建到被調(diào)度執(zhí)行期間循環(huán)變量極有可能被改寫(xiě),所以會(huì)出現(xiàn)兩次結(jié)果相差較大,比如第一個(gè)協(xié)程啟動(dòng)for range變量正好循環(huán)到3,for屬于主協(xié)程的一部分。go func是子協(xié)程,主子分開(kāi)看。這種情況下,其實(shí)for range里面的循環(huán)變量沒(méi)有跟子協(xié)程綁定,稱(chēng)之為變量沒(méi)有綁定。所以,題目一打印結(jié)果是混亂的。很有可能(隨機(jī))所有協(xié)程執(zhí)行的task都是列表中的最后一個(gè)task,也可能不是。

在題目二中,協(xié)程函數(shù)體中并沒(méi)有直接引用循環(huán)變量task,而是使用的參數(shù)與協(xié)程進(jìn)行了綁定。而在創(chuàng)建協(xié)程時(shí),循環(huán)變量task

作為函數(shù)參數(shù)傳遞給了協(xié)程。參數(shù)傳遞的過(guò)程實(shí)際上也生成了新的變量,也即間接完成了綁定。

所以,題目二實(shí)際上是沒(méi)有問(wèn)題的。就是實(shí)際參數(shù)順序是按照f(shuō)or range產(chǎn)生的變量順序綁定給子協(xié)程的。

ps:

簡(jiǎn)單點(diǎn)來(lái)說(shuō)

如果循環(huán)體沒(méi)有并發(fā)出現(xiàn),則引用循環(huán)變量一般不會(huì)出現(xiàn)問(wèn)題;

如果循環(huán)體有并發(fā),則根據(jù)引用循環(huán)變量的位置不同而有所區(qū)別

通過(guò)參數(shù)完成綁定,則一般沒(méi)有問(wèn)題;

函數(shù)體中引用,則需要顯式地綁定

補(bǔ)充:Go語(yǔ)言的協(xié)程中,寫(xiě)死循環(huán)的注意點(diǎn):

現(xiàn)象:

在寫(xiě)Go的多協(xié)程程序時(shí),出現(xiàn)過(guò)幾次無(wú)法理解的情況。

有一次,我想寫(xiě)一個(gè)能跑滿(mǎn)cpu的程序,最容易想到的就是,開(kāi)幾個(gè)Go的協(xié)程,每個(gè)協(xié)程里寫(xiě)死循環(huán)。沒(méi)想到,運(yùn)行的時(shí)候發(fā)現(xiàn),協(xié)程就只開(kāi)出了一個(gè)。

另一次,我寫(xiě)了個(gè)程序,也是開(kāi)了多個(gè)協(xié)程。因?yàn)槿绻蛔枞≈骱瘮?shù),主函數(shù)一結(jié)束,程序就會(huì)結(jié)束。所以我就在主函數(shù)結(jié)束前加了個(gè)死循環(huán)。然后就發(fā)現(xiàn)整個(gè)協(xié)程都被卡住了。

分析:

其實(shí),這個(gè)東西是協(xié)程的特點(diǎn)。以前沒(méi)用過(guò)協(xié)程,加上Go又說(shuō)可以當(dāng)線程用。所以想當(dāng)然的寫(xiě)了死循環(huán)。

準(zhǔn)確的說(shuō),是在Go語(yǔ)言里,寫(xiě)了死循環(huán),并且死循環(huán)內(nèi)并沒(méi)有什么系統(tǒng)調(diào)用,只有簡(jiǎn)單的計(jì)算這類(lèi)的。你就會(huì)發(fā)現(xiàn),Go的協(xié)程調(diào)度就廢掉了。

協(xié)程并非像線程那樣,是由CPU中斷來(lái)觸發(fā)切換的。它不是應(yīng)用程序能控制的(操作系統(tǒng)內(nèi)核的某些關(guān)鍵操作會(huì)被保護(hù),不被中斷)。即使你在線程里寫(xiě)了死循環(huán),只要周期一到,CPU產(chǎn)生終端,死循環(huán)會(huì)被打斷,重新調(diào)度。但是,協(xié)程就不是這樣了,協(xié)程的調(diào)度其實(shí)是在協(xié)程調(diào)用了某個(gè)系統(tǒng)調(diào)用時(shí),自動(dòng)跳到另一個(gè)協(xié)程執(zhí)行。也就是這個(gè)“中斷”是程序主動(dòng)產(chǎn)生的,而不是被”中斷”。

所以,協(xié)程中,如果你寫(xiě)了死循環(huán),那你的死循環(huán)就會(huì)一直跑著,而不會(huì)讓別的協(xié)程運(yùn)行。主函數(shù)中也是一樣,而且主函數(shù)中執(zhí)行這個(gè)會(huì)讓整個(gè)協(xié)程卡住,因?yàn)檎{(diào)度的代碼沒(méi)法被執(zhí)行。

在Go語(yǔ)言中,如果你想寫(xiě)死循環(huán),循環(huán)里面沒(méi)有系統(tǒng)調(diào)用,又想讓Go的協(xié)程能起作用,只需要在死循環(huán)里面加一條語(yǔ)句即可。估計(jì)系統(tǒng)調(diào)用時(shí)也是這個(gè)語(yǔ)句起的作用。

runtime.Gosched() //主動(dòng)讓出時(shí)間片

還可以使用

select{}

來(lái)實(shí)現(xiàn)無(wú)限阻塞,而不是使用for{}

以上為個(gè)人經(jīng)驗(yàn),希望能給大家一個(gè)參考,也希望大家多多支持腳本之家。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教。

相關(guān)文章

  • Go實(shí)現(xiàn)快速生成固定長(zhǎng)度的隨機(jī)字符串

    Go實(shí)現(xiàn)快速生成固定長(zhǎng)度的隨機(jī)字符串

    這篇文章主要為大家詳細(xì)介紹了怎樣在Go中簡(jiǎn)單快速地生成固定長(zhǎng)度的隨機(jī)字符串,文中的示例代碼講解詳細(xì),具有一定的借鑒價(jià)值,需要的可以學(xué)習(xí)一下
    2022-10-10
  • Go語(yǔ)言實(shí)現(xiàn)LRU算法的核心思想和實(shí)現(xiàn)過(guò)程

    Go語(yǔ)言實(shí)現(xiàn)LRU算法的核心思想和實(shí)現(xiàn)過(guò)程

    這篇文章主要介紹了Go語(yǔ)言實(shí)現(xiàn)LRU算法的核心思想和實(shí)現(xiàn)過(guò)程,LRU算法是一種常用的緩存淘汰策略,它的核心思想是如果一個(gè)數(shù)據(jù)在最近一段時(shí)間內(nèi)沒(méi)有被訪問(wèn)到,那么在將來(lái)它被訪問(wèn)的可能性也很小,因此可以將其淘汰,感興趣想要詳細(xì)了解可以參考下文
    2023-05-05
  • Go語(yǔ)言與gRPC的完美結(jié)合實(shí)戰(zhàn)演練

    Go語(yǔ)言與gRPC的完美結(jié)合實(shí)戰(zhàn)演練

    這篇文章主要介紹了Go語(yǔ)言與gRPC的完美結(jié)合實(shí)戰(zhàn)演練,gRPC(Remote?Procedure?Call)是一種遠(yuǎn)程過(guò)程調(diào)用技術(shù),通過(guò)壓縮和序列化數(shù)據(jù)來(lái)優(yōu)化網(wǎng)絡(luò)通信,可以顯著提高服務(wù)調(diào)用的性能和效率
    2024-01-01
  • 在Go中創(chuàng)建隨機(jī)的安全密碼

    在Go中創(chuàng)建隨機(jī)的安全密碼

    今天小編就為大家分享一篇關(guān)于在Go中創(chuàng)建隨機(jī)的安全密碼,小編覺(jué)得內(nèi)容挺不錯(cuò)的,現(xiàn)在分享給大家,具有很好的參考價(jià)值,需要的朋友一起跟隨小編來(lái)看看吧
    2018-10-10
  • Golang語(yǔ)言的多種變量聲明方式與使用場(chǎng)景詳解

    Golang語(yǔ)言的多種變量聲明方式與使用場(chǎng)景詳解

    Golang當(dāng)中的變量類(lèi)型和C/C++比較接近,一般用的比較多的也就是int,float和字符串,下面這篇文章主要給大家介紹了關(guān)于Golang語(yǔ)言的多種變量聲明方式與使用場(chǎng)景的相關(guān)資料,需要的朋友可以參考下
    2022-02-02
  • Golang 1.18新特性模糊測(cè)試用法詳解

    Golang 1.18新特性模糊測(cè)試用法詳解

    模糊測(cè)試是一種軟件測(cè)試技術(shù)。其核心思想是將自動(dòng)或半自動(dòng)生成的隨機(jī)數(shù)據(jù)輸入到一個(gè)程序中,并監(jiān)視程序異常,如崩潰,斷言失敗,以發(fā)現(xiàn)可能的程序錯(cuò)誤,比如內(nèi)存泄漏,本文給大家介紹了Golang 1.18 新特性模糊測(cè)試,感興趣的同學(xué)可以參考閱讀下
    2023-05-05
  • golang高并發(fā)系統(tǒng)限流策略漏桶和令牌桶算法源碼剖析

    golang高并發(fā)系統(tǒng)限流策略漏桶和令牌桶算法源碼剖析

    這篇文章主要介紹了golang高并發(fā)系統(tǒng)限流策略漏桶和令牌桶算法源碼剖析,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪
    2022-06-06
  • golang 常用定時(shí)任務(wù)匯總

    golang 常用定時(shí)任務(wù)匯總

    這篇文章主要介紹了golang 常用定時(shí)任務(wù)匯總,golang利用goroutine外加github.com/gorhill/cronexpr庫(kù)就可實(shí)現(xiàn)定時(shí)任務(wù),具體代碼介紹,需要的小伙伴可以參考一下
    2022-09-09
  • Gin golang web開(kāi)發(fā)模型綁定實(shí)現(xiàn)過(guò)程解析

    Gin golang web開(kāi)發(fā)模型綁定實(shí)現(xiàn)過(guò)程解析

    這篇文章主要介紹了Gin golang web開(kāi)發(fā)模型綁定實(shí)現(xiàn)過(guò)程解析,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友可以參考下
    2020-10-10
  • Golang全局變量加鎖的問(wèn)題解決

    Golang全局變量加鎖的問(wèn)題解決

    這篇文章主要介紹了解決Golang全局變量加鎖的問(wèn)題,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過(guò)來(lái)看看吧
    2021-05-05

最新評(píng)論

黄龙县| 镇平县| 南宫市| 阿拉善右旗| 双流县| 三亚市| 沅陵县| 桓台县| 和林格尔县| 黄骅市| 蒲江县| 台山市| 如皋市| 南昌县| 玉门市| 板桥市| 易门县| 双城市| 广河县| 增城市| 沿河| 德安县| 白沙| 日土县| 五原县| 乐山市| 镇坪县| 宁武县| 星子县| 五莲县| 东光县| 含山县| 邵东县| 绥中县| 盘锦市| 漳平市| 剑河县| 阳泉市| 太原市| 凤凰县| 吉安市|