簡體   English   中英

goroutines如何運作?

[英]How do goroutines work?

我正在關注Go Tour ,當涉及到goroutines時我有點卡住了。 我知道他們非常輕量級,每次goroutine阻止,另一個將開始,但我無法理解這個例子實際上是如何工作的:

package main

import (
    "fmt"
    "time"
)

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

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

操場

據我所知,一個goroutine是針對具有參數“world”的say函數啟動的,但據我所知,應該打印“world”五次並且“hello”一次。 但是我不明白為什么輸出是這樣的:

hello
world
hello
world
hello
world
hello
world
hello

從我對其他語言的線程的有限理解,輸出應該是這樣的:

hello
world
world
world
world
world

或者像這樣:

world 
world
world
hello
world
world

為什么第二行也執行五次? go語句下面的任何內容都go歸類為go例程的一部分嗎?

下一張幻燈片還顯示了我無法再次回頭看的內容:

package main

import "fmt"

func sum(a []int, c chan int) {
    sum := 0
    for _, v := range a {
        sum += v
    }
    c <- sum // send sum to c
}

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

    c := make(chan int)
    go sum(a[:len(a)/2], c)
    go sum(a[len(a)/2:], c)
    x, y := <-c, <-c // receive from c

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

操場

對於切片的后半部分開始goroutine,然后為切片的第一部分開始另一個goroutine,但是值xy已經被分配了兩個不同的值。 我看到它的方式sum函數將它的總和發送到通道c ,然后下一個sum將它的總和發送到相同的通道c那么如何為這兩個變量分配兩個不同的值? 通道c不應該有一個單一的sum值嗎?

我很欣賞這是一個很長的問題,但我無法找到這些問題的答案。

為什么第二行也執行5次?

第二行將在main()線程中每隔5次打印hello
同時第一行go say("world")也將在一個單獨的goroutine中每秒打印五次世界。
Sleep確保每個例程產生,允許另一個例程恢復。

因此輸出:

hello
world
hello
world
hello
world
hello
world
hello

我看到它的方式sum函數將它的總和發送到通道c,然后下一個和將它的總和發送到相同的通道c,那么如何為這兩個變量分配兩個不同的值?

因為每個發送都將在c阻塞,直到讀取通道c
由於有兩個寫入c ,您需要閱讀:

 x, y := <-c, <-c // receive from c twice.

Golang SpecAssignement部分允許在以下情況下進行元組賦值:

左邊的操作數數量必須等於右邊的表達式數量,每個表達式必須是單值,右邊的nth表達式分配給左邊的第n個操作數。

對於第一個函數,您應該看到VonC所呈現的值。 hello打印5次的原因是因為函數say打印東西5次。 想象一下沒有goroutine的程序。 我認為這並不能保證你會得到helloworld完美穿插,但我可能錯了。

頻道工作的原因是:

  1. Golang讓你做VonC提到的多項任務
  2. empty out通道,即當你將c分配給x它會移除傳遞給通道的第一個總和,當它將c分配給y它傳遞給第二個值(再次我認為順序不是保證,因為x可以具有第一半部和y下半年總和或反之亦然。

如果你把頻道想象成一種隊列我覺得它更有意義。 求和goroutines將值推送到隊列,並且賦值按順序彈出值。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM