У меня нет рутины, но все равно получаешь "все рутины спят - тупик" - PullRequest
0 голосов
/ 29 сентября 2019

Я проводил несколько экспериментов. Ниже приведен мой код.

package main

import (
  "fmt"
  "time"
)

func main(){
  var a chan int
  a = make(chan int)
  for j:=0;j<10;j++{
    firstRoutine(a, j)
    time.Sleep(3 * time.Millisecond)
  }
}

func firstRoutine(chennel chan int, j int){
  i:=0
  fmt.Println("j = ", j, "chennel = ", chennel)
  chennel <- i
}

Вывод:

F:\Git\GitHub\GO\Prog\Concorrency>go run Channels.go
j =  0 chennel =  <nil>
fatal error: all goroutines are asleep - deadlock!

goroutine 1 [chan send (nil chan)]:
main.firstRoutine(0x0, 0x0)
        F:/Git/GitHub/GO/Prog/Concorrency/Channels.go:24 +0x11f
main.main()
        F:/Git/GitHub/GO/Prog/Concorrency/Channels.go:14 +0x3f
exit status 2

У меня нет gorutines в моей программе, но все равно появляется эта ошибка.

НижеПрограмма работает, по крайней мере, нет ошибки Goroutine. единственное изменение go firstRoutine(a, j)

package main

import (
  "fmt"
  "time"
)

func main(){

  var a chan int
  a = make(chan int)
  for j:=0;j<10;j++{
    go firstRoutine(a, j)
    time.Sleep(3 * time.Millisecond)
  }
}

func firstRoutine(chennel chan int, j int){
  i:=0
  fmt.Println("j = ", j, "chennel = ", chennel)
  chennel <- i
}

Выход:

F:\Git\GitHub\GO\Prog\Concorrency>go run Channels.go
j =  0 chennel =  0xc000048060
j =  1 chennel =  0xc000048060
j =  2 chennel =  0xc000048060
j =  3 chennel =  0xc000048060
j =  4 chennel =  0xc000048060
j =  5 chennel =  0xc000048060
j =  6 chennel =  0xc000048060
j =  7 chennel =  0xc000048060
j =  8 chennel =  0xc000048060
j =  9 chennel =  0xc000048060

1 Ответ

2 голосов
/ 29 сентября 2019

вы пишете / отправляете данные на канал, но не читаете / не получаете данные с того же канала. Запись / чтение в канал блокируется, если вы не читаете / не записываете данные из него.

пишите цикл for, который считывает данные из канала a или использует буферизованный канал

При добавлении некоторых журналов обнаруживаетсявторой случай.

Во втором случае вы создали 10 отдельных подпрограмм go, но все они заблокированы, потому что данные никогда не читаются из канала a, и после 10 итераций выход из цикла for сопровождается основной функцией.

package main

import (
  "fmt"
  "time"
)

func main(){

  var a chan int
  a = make(chan int)
  for j:=0;j<10;j++{
    go firstRoutine(a, j)
    fmt.Println("sleeping")
    time.Sleep(3 * time.Millisecond)
    fmt.Println("awake")
  }
}

func firstRoutine(chennel chan int, j int){
  i:=0
  fmt.Println("j = ", j, "chennel = ", chennel)
  chennel <- i
  fmt.Println("pushed to channel"); // never gets printed
}

При использовании буферизованного канала:

package main

import (
  "fmt"
  "time"
)

func main(){

  var a chan int
  a = make(chan int, 11) // making a buffered channel of 11 elements
  for j:=0;j<10;j++{
    go firstRoutine(a, j)
    fmt.Println("sleeping")
    time.Sleep(3 * time.Millisecond)
    fmt.Println("awake")
  }
}

func firstRoutine(chennel chan int, j int){
  i:=0
  fmt.Println("j = ", j, "chennel = ", chennel)
  chennel <- i
  fmt.Println("pushed to channel"); // gets printed as buffer is bigger than the iterations, so no blocking
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...