亚洲激情专区-91九色丨porny丨老师-久久久久久久女国产乱让韩-国产精品午夜小视频观看

溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點擊 登錄注冊 即表示同意《億速云用戶服務條款》

golang中協程的怎么在for循環中使用

發布時間:2020-12-22 14:01:00 來源:億速云 閱讀:282 作者:Leah 欄目:開發技術

golang中協程的怎么在for循環中使用?針對這個問題,這篇文章詳細介紹了相對應的分析和解答,希望可以幫助更多想解決這個問題的小伙伴找到更簡單易行的方法。

兩個例子

package main 
import (
 "fmt"
 "time"
)
 
func Process1(tasks []string) {
 for _, task := range tasks {
 // 啟動協程并發處理任務
 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)
}

結果:

第一次運行

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

第二次運行

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 {
 // 啟動協程并發處理任務
 go func() {
 fmt.Printf("Worker start process task: %s\n", task)
 }()
 }
}
 
func Process2(tasks []string) {
 for _, task := range tasks {
 // 啟動協程并發處理任務
 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)
}

結果

第一次運行

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

第二次運行

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

上述問題,有個共同點就是都引用了循環變量。即在for index, value := range xxx語句中,

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

循環變量是易變的

首先,循環變量實際上只是一個普通的變量。

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

如果循環體中會啟動協程(并且協程會使用循環變量),就需要格外注意了,因為很可能循環結束后協程才開始執行,

此時,所有協程使用的循環變量有可能已被改寫。(是否會改寫取決于引用循環變量的方式)

循環變量需要綁定

在題目一中,協程函數體中引用了循環變量task,協程從被創建到被調度執行期間循環變量極有可能被改寫,所以會出現兩次結果相差較大,比如第一個協程啟動for range變量正好循環到3,for屬于主協程的一部分。go func是子協程,主子分開看。這種情況下,其實for range里面的循環變量沒有跟子協程綁定,稱之為變量沒有綁定。所以,題目一打印結果是混亂的。很有可能(隨機)所有協程執行的task都是列表中的最后一個task,也可能不是。

在題目二中,協程函數體中并沒有直接引用循環變量task,而是使用的參數與協程進行了綁定。而在創建協程時,循環變量task

作為函數參數傳遞給了協程。參數傳遞的過程實際上也生成了新的變量,也即間接完成了綁定。

所以,題目二實際上是沒有問題的。就是實際參數順序是按照for range產生的變量順序綁定給子協程的。

ps:

簡單點來說

如果循環體沒有并發出現,則引用循環變量一般不會出現問題;

如果循環體有并發,則根據引用循環變量的位置不同而有所區別

通過參數完成綁定,則一般沒有問題;

函數體中引用,則需要顯式地綁定

補充:Go語言的協程中,寫死循環的注意點:

現象:

在寫Go的多協程程序時,出現過幾次無法理解的情況。

有一次,我想寫一個能跑滿cpu的程序,最容易想到的就是,開幾個Go的協程,每個協程里寫死循環。沒想到,運行的時候發現,協程就只開出了一個。

另一次,我寫了個程序,也是開了多個協程。因為如果不阻塞住主函數,主函數一結束,程序就會結束。所以我就在主函數結束前加了個死循環。然后就發現整個協程都被卡住了。

分析:

其實,這個東西是協程的特點。以前沒用過協程,加上Go又說可以當線程用。所以想當然的寫了死循環。

準確的說,是在Go語言里,寫了死循環,并且死循環內并沒有什么系統調用,只有簡單的計算這類的。你就會發現,Go的協程調度就廢掉了。

協程并非像線程那樣,是由CPU中斷來觸發切換的。它不是應用程序能控制的(操作系統內核的某些關鍵操作會被保護,不被中斷)。即使你在線程里寫了死循環,只要周期一到,CPU產生終端,死循環會被打斷,重新調度。但是,協程就不是這樣了,協程的調度其實是在協程調用了某個系統調用時,自動跳到另一個協程執行。也就是這個“中斷”是程序主動產生的,而不是被”中斷”。

所以,協程中,如果你寫了死循環,那你的死循環就會一直跑著,而不會讓別的協程運行。主函數中也是一樣,而且主函數中執行這個會讓整個協程卡住,因為調度的代碼沒法被執行。

在Go語言中,如果你想寫死循環,循環里面沒有系統調用,又想讓Go的協程能起作用,只需要在死循環里面加一條語句即可。估計系統調用時也是這個語句起的作用。

runtime.Gosched() //主動讓出時間片

還可以使用

select{}

來實現無限阻塞,而不是使用for{}

關于golang中協程的怎么在for循環中使用問題的解答就分享到這里了,希望以上內容可以對大家有一定的幫助,如果你還有很多疑惑沒有解開,可以關注億速云行業資訊頻道了解更多相關知識。

向AI問一下細節

免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。

AI

都匀市| 宿松县| 灵石县| 夏津县| 泾源县| 固原市| 乌拉特后旗| 永胜县| 仪征市| 视频| 安丘市| 泉州市| 靖西县| 榕江县| 邢台县| 巴彦淖尔市| 荣成市| 双桥区| 自贡市| 大冶市| 余姚市| 梅河口市| 南阳市| 湄潭县| 绥江县| 尤溪县| 民和| 杭锦旗| 榆树市| 秦安县| 丽水市| 乐都县| 定南县| 甘德县| 翁牛特旗| 商南县| 原平市| 洪湖市| 墨脱县| 三都| 虹口区|