Порядок исполнения горутин - PullRequest
0 голосов
/ 01 марта 2019

Я очень плохо знаком с Голангом.

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

a=1 first executed
a=1 second executed
panic: b != 1

Если он напечатает

a = 1
a = 1 first executed 
Response true
and so on

или

b =1 
b = 1 first executed 
Response true
and so on

С момента отправки значения в канал,соответствующая процедура должна заблокировать и ждать получателя?

 func main() {
            var a, b int
            var c = make(chan bool)
            go func() {
                b = 1
                fmt.Println("b=1 first executed")
                c <- true
                fmt.Println("b=1 second executed")
                if a != 1 { // impossible
                    panic("a != 1") // will never happen
                }
                fmt.Println("b=1 third executed")
            }()
            go func() {
                a = 1
                fmt.Println("a=1 first executed")
                c <- true
                fmt.Println("a=1 second executed")
                if b != 1 { // impossible
                    panic("b != 1") // will never happen
                }
                fmt.Println("a=1 third executed")
            }()

            fmt.Println("Response ", <-c)
            fmt.Println("Main executed")
            }

Ответы [ 2 ]

0 голосов
/ 01 марта 2019

Я предполагаю, что вы работаете на детской площадке.При использовании Go Playground следует помнить одну вещь: Он имеет фиксированное время и фиксированный псевдослучайный генератор.

Это означает, что вы не можете использовать Playground для наблюдения случайных результатов.,И порядок выполнения Goroutine, или концепции параллелизма Go в целом, основан на равномерной псевдослучайности.

Запустив ваш код на моем терминале, он даст разные результаты:

➜  basic1 GOMAXPROCS=1 ./basic1
a=1 first executed
a=1 second executed
a=1 third executed
Response  true
Main executed
➜  basic1 GOMAXPROCS=1 ./basic1
a=1 first executed
a=1 second executed
panic: b != 1

goroutine 6 [running]:
main.main.func2(0xc000012088, 0xc000054060, 0xc0000120a0)
        /mnt/f/home/leaf/spike/stackoverflow/concur/basic1/main.go:26 +0x13b
created by main.main
        /mnt/f/home/leaf/spike/stackoverflow/concur/basic1/main.go:20 +0xed
➜  basic1 GOMAXPROCS=1 ./basic1
a=1 first executed
a=1 second executed
a=1 third executed
b=1 first executed
Response  true
Main executed

Но есть кое-что еще.Как я уже упоминал, одновременный порядок исключений Go является случайным.Нет гарантии того, что будет первым, если только не будет синхронизации.

Синхронизация включает в себя обмен данными по каналам и материалы от sync.

В вашем коде происходит только одна синхронизация, котораяобщение через c.Это гарантирует одну вещь: когда main() goroutine получает свои Response, по крайней мере , одна из порожденных там goroutines напечатала свою "исключенную".

Нетгарантировать, что какой-либо из них выполняется, ни то, ни другое или только одно выполнено, а также не выполнено ли выполнение goroutine оператора if, содержащего panic first .

Edit:

Далеечтение:

0 голосов
/ 01 марта 2019

Единственная синхронизация между этими двумя программами - отправка на c.Поскольку из c считывается только одно значение, только одна из двух операций отправки c <- true проходит, а остальные блокируются навсегда.

Предположим, что первая программа запускается первой (случайно), и выполняет send и оба Printlns, в то время как вторая программа вообще не начала выполняться.Это допустимый режим работы, который будет отображать вывод, который вы видите.

Ваша синхронизация через c равна не между двумя анонимными программами, но между программами и внешним f3 только.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...