V
V
Vladimir Grabko2016-06-14 01:25:13
go
Vladimir Grabko, 2016-06-14 01:25:13

Why do errors appear after the “death” of a worker?

Googling, I realized that in go all my problems will be solved by the worker. That's what I'm on shitcode

package main

import "fmt"
import "sync"

import "time"

var wg sync.WaitGroup

func worker(id int, jobs <-chan int, results chan<- int) {
  defer func() { wg.Done() }()
  for j := range jobs {
    fmt.Println("worker", id, "processing job", j)
    time.Sleep(time.Second)
    results <- j
  }
}

func main() {
  jobs := make(chan int, 100)
  results := make(chan int, 100)

  for w := 1; w <= 10; w++ {
    wg.Add(1)
    go worker(w, jobs, results)
  }

  for j := 1; j <= 90; j++ {
    jobs <- j
  }

  for msg := range results {
    fmt.Println("worker", msg)
  }

  wg.Wait()
  close(jobs)
  close(results)
  fmt.Println("main finished")

}

Errors after code completes
fatal error: all goroutines are asleep - deadlock!

goroutine 1 [chan receive]:
main.main()
        C:/Documents and Settings/lucifer/Рабочий ст
 +0x12d

goroutine 5 [chan receive]:
main.worker(0x1, 0x10744000, 0x107441e0)
        C:/Documents and Settings/lucifer/Рабочий ст
 +0x66
created by main.main
        C:/Documents and Settings/lucifer/Рабочий ст
 +0xc3

Answer the question

In order to leave comments, you need to log in

2 answer(s)
F
fastpars, 2016-06-14
@VGrabko

After for j do close(jobs), then for range cancel will end after removing the last element from the channel

K
Kana, 2016-06-18
@kana-desu

Working example at play.golang.org

package main

import (
  "fmt"
  "sync"
  "time"
)

var wg sync.WaitGroup

func worker(id int, jobs <-chan int, results chan<- int) {
  defer wg.Done()
  
  for j := range jobs {
    fmt.Println("worker", id, "processing job", j)
    time.Sleep(time.Second)
    results <- j
  }
}

func main() {
  jobs := make(chan int, 100)
  results := make(chan int, 100)

  for w := 1; w <= 5; w++ {
    wg.Add(1)
    go worker(w, jobs, results)
  }

  for j := 1; j <= 10; j++ {
    jobs <- j
  }

  close(jobs)
  wg.Wait()
  close(results)

  for msg := range results {
    fmt.Println("worker", msg)
  }

  fmt.Println("main finished")
}

Didn't find what you were looking for?

Ask your question

Ask a Question

731 491 924 answers to any question