Я заметил несоответствие в том, как некоторые статьи (и собственная документация golang) описывают операции канала и то, что я видел на самом деле.
Это связано с тем, как Go блоков на чтение / запись канала. Я теперь читал во многих местах, что горутина блокирует выполнение всякий раз, когда она видит чтение или запись в канал, что означает, что она либо ожидает получения данных, либо ждет, пока другая горутина получит данные из канала.
Но если вы посмотрите на следующий пример, это явно не то, что происходит при второй записи.
package main
import (
"fmt"
)
func firstFunc(ch chan string) {
fmt.Println("firstFunc Hello", <-ch)
fmt.Println("firstFunc() carries on getting called")
}
func secondFunc(ch chan string) {
fmt.Println("secondFunc Hello", <-ch)
fmt.Println("secondFunc() carries on getting called")
}
func main() {
fmt.Println("main() started")
c1 := make(chan string)
c2 := make(chan string)
go firstFunc(c1)
go secondFunc(c2)
c1 <- "John"
c2 <- "Bob"
fmt.Println("main() ended")
}
Вот как я интерпретирую, что Go выполняет этот код:
- он печатает запущенное main () сообщение, создает каналы c1 и c2 и ставит в очередь firstFun c и secondFun c горутины (но не выполняет их в этот момент)
- он попадает в c1 < - «Джон» и блокирует его до тех пор, пока другая горутина не прочитает из этого канала
- , в этот момент он планирует firstFun c, который читает из c1 и продолжает выполнение остальной части кода до конца функции
- main () снова переназначен, и следующая строка - C2 <- "Bob", на этом этапе я бы подумал, что main () должен снова заблокироваться, как это было с "John" и дождитесь, пока secondFun c прочитает его, прежде чем продолжить. Но этого не происходит. Результат: </li>
main() started
firstFunc Hello John
firstFunc() carries on getting called
main() ended
он не просто блокирует запись в «Боб», а вместо этого продолжает выполнение до тех пор, пока main () не будет завершен, и никогда не планирует secondFun c.
Это стало для меня препятствием на пути к изучению Go, поскольку я не уверен, что это статьи, которым я не могу доверять, или есть пробел в моем понимании.
Я был бы очень признателен за помощь в этом.