Нужна небольшая помощь, чтобы понять поток кода? я не понимаю, как конец процедуры в выходных данных находится между другими операторами вывода - PullRequest
0 голосов
/ 01 апреля 2020

Пытаясь понять поток подпрограмм, поэтому я написал этот код только одна вещь, которую я не могу понять, это то, как завершение рутины проходит между другими подпрограммами go и завершает одну подпрограмму go и печатает выход из канала в конце.


import(
    "fmt"
)


func add(dataArr []int,dataChannel chan int,i int ){
    var sum int
    fmt.Println("GOROUTINE",i+1)
    for i:=0;i<len(dataArr);i++{
        sum += dataArr[i]
    }
    fmt.Println("wRITING TO CHANNEL.....")
    dataChannel <- sum

    fmt.Println("routine-end")
}


func main(){
    fmt.Println("main() started")
    dataChannel := make(chan int)
    dataArr := []int{1,2,3,4,5,6,7,8,9}
    for i:=0;i<len(dataArr);i+=3{

        go add(dataArr[i:i+3],dataChannel,i)
    }   
    fmt.Println("came to blocking statement ..........")
    fmt.Println(<-dataChannel)

    fmt.Println("main() end")

}
output

main() started
came to blocking statement ..........
GOROUTINE 1
wRITING TO CHANNEL.....
routine-end
GOROUTINE 4
wRITING TO CHANNEL.....
6
main() end

1 Ответ

1 голос
/ 01 апреля 2020

Ваш for l oop запускает 3 процедуры, которые вызывают функцию add.

Кроме того, main сам работает в отдельной "главной" программе.

Поскольку подпрограммы выполняются одновременно, порядок их выполнения обычно непредсказуем и зависит от времени, загруженности вашей машины и т. Д. c. Результаты могут отличаться между пробегами и между машинами. Вставка time.Sleep вызовов в разных местах может помочь визуализировать это. Например, вставка time.Sleep за 100 мс до «оператора блокировки» показывает, что все add запускаются программы.

Как правило, вы можете увидеть, что один запуск add запускает, добавляет его фрагмент к sum и записывает sum в dataChannel. Поскольку main запускает несколько подпрограмм и сразу читает из канала, это чтение получает sum, записанное add, и затем программа существует - потому что по умолчанию main не будет ждать завершения всех подпрограмм до конца sh.

Более того, поскольку канал dataChannel небуферизован и main читает только одно значение, другие процедуры add будут блокировать канал на неопределенный срок во время записи.


Я рекомендую просмотреть некоторые вводные ресурсы для процедур и каналов. Они строят концепции из простых принципов. Несколько хороших ссылок для вас:

...