Планирование нескольких Goroutines - PullRequest
0 голосов
/ 22 июня 2019
package main

import "fmt"


func square(c chan int) {
    fmt.Println("[square] reading (4)")
    num := <-c
    fmt.Println("[square] calc (5)")
    c <- num * num
    fmt.Println("back from [square] (10)")
}

func cube(c chan int) {
    fmt.Println("[cube] reading (3)")
    num := <-c
    fmt.Println("[cube] calc (11)")
    c <- num * num * num
    fmt.Println("back from [cube] (12)")
}

func main() {
    fmt.Println("[main] main() started (1)")

    squareChan := make(chan int)
    cubeChan := make(chan int)

    go square(squareChan)
    go cube(cubeChan)

    testNum := 3
    fmt.Println("[main] sent testNum to squareChan (2)")

    squareChan <- testNum

    fmt.Println("[main] resuming (6)")
    fmt.Println("[main] sent testNum to cubeChan (7)")

    cubeChan <- testNum // why doesn't block here?

    fmt.Println("[main] resuming (8)")
    fmt.Println("[main] reading from channels (9)")

    squareVal, cubeVal := <-squareChan, <-cubeChan
    fmt.Println("[main] waiting calculating (13)")

    fmt.Println("[main] results: ", squareVal, cubeVal)
    fmt.Println("[main] main() stopped")
}

вывод:

[main] main() started (1)
[main] sent testNum to squareChan (2)
[cube] reading (3)
[square] reading (4)
[square] calc (5)
[main] resuming (6)
[main] sent testNum to cubeChan (7)
[main] resuming (8)
[main] reading from channels (9)
back from [square] (10)
[cube] calc (11)
back from [cube] (12)
[main] waiting calculating (13)
[main] results:  9 27
[main] main() stopped

В приведенном выше коде я думаю, что подпрограмма main() должна быть заблокирована после cubeChan <- testNum, затем должна быть запланирована подпрограмма cube, что означаетвывод [cube] calc (11) должен быть до [main] resuming (8).Но после выполнения на Playground, я так растерялся из-за вывода.

Может кто-нибудь сказать мне, если я что-то не так понял?

Ответы [ 2 ]

0 голосов
/ 19 июля 2019

Я думаю, что вы неправильно понимаете постоянный код.

Но каналы блокируют поток, только если им нечего выводить или они заполнены.И каналы могут быть заполнены только, если вы укажете размер.

Я также не рекомендую использовать один и тот же канал для ввода и вывода для функции

При вашем текущем методе вы можете столкнуться с проблемами здесь

cubeChan <- testNum 

fmt.Println("[main] resuming (8)")
fmt.Println("[main] reading from channels (9)")

squareVal, cubeVal := <-squareChan, <-cubeChan

Если ваша функция куба слишком медленная по любой возможной причине, то testNum, который вы добавляете в cubechan, может быть немедленно удален с этой строкой здесь

squareVal, cubeVal := <-squareChan, <-cubeChan
0 голосов
/ 22 июня 2019

Я думаю, что подпрограмма main () должна быть заблокирована после cubeChan <- testNum </p>

блокируется, но при следующих значениях:

squareVal, cubeVal := <-squareChan, <-cubeChan
                      ^             ^

, если squareChan или cubeChan не получит никаких значений в других подпрограммах, эта строка станет тупиковой, измените cube(), как показано ниже, чтобы увидеть эффект:

func cube(c chan int) {
    fmt.Println("[cube] reading (3)")
    _ = <-c
    fmt.Println("[cube] calc (11)")
    // c <- num * num * num
    fmt.Println("back from [cube] (12)")
}
...