go - Golang deadlock that I resolved by luck, need explanation -


i'm trying understand go channel , go routine. so, i'm doing online exercises. found 1 here: http://whipperstacker.com/2015/10/05/3-trivial-concurrency-exercises-for-the-confused-newbie-gopher/

i resolved 3rd 1 (named "internet cafe"). there's resolved "luck", , it's bother me because don't understand issue , why "hack" fixed it.

in code below, replace "enterchan <- next" "go func() { enterchan <- next }()", , solved deadlock.

can explain me why deadlock before, , why works hack ? proper solution, or ugly 1 ?

don't hesitate criticize code, i'm searching improve :)

many thanks!

this code:

package main  import (     "fmt"     "math/rand"     "strconv"     "time" )  const (     maxnumberofuser = 8 )  func usecomputer(tourist string, leaverchan chan string) {     seed := rand.newsource(time.now().unixnano())     random := rand.new(seed)     fmt.println(tourist, "is online")     d := random.intn(120-15) + 15     time.sleep(time.duration(d) * time.millisecond * 10)     fmt.println(tourist, "is done, having spent", d, "minutes online.")     leaverchan <- tourist }  func manageusers(enterchan, leaverchan chan string, stopchan chan struct{}) {     nbused := 0     queue := make([]string, 0)     {         select {         case tourist := <-enterchan:             if nbused < maxnumberofuser {                 nbused++                 go usecomputer(tourist, leaverchan)             } else {                 fmt.println(tourist, "waiting turn.")                 queue = append(queue, tourist)             }         case tourist := <-leaverchan:             nbused--             fmt.println(tourist, "is leaving, number of free place now:", maxnumberofuser-nbused)             if len(queue) > 0 {                 next := queue[0]                 queue = queue[1:]                 go func() {                     enterchan <- next                 }()             } else if nbused == 0 {                 close(stopchan)                 return             }          }     } }  func main() {     enterchan := make(chan string)     leaverchan := make(chan string)     stopchan := make(chan struct{})     go manageusers(enterchan, leaverchan, stopchan)      := 1; <= 25; i++ {         enterchan <- "tourist " + strconv.itoa(i)     }     <-stopchan     fmt.println("the place empty, let's close , go beach!") } 


Comments

Popular posts from this blog

android - InAppBilling registering BroadcastReceiver in AndroidManifest -

python Tkinter Capturing keyboard events save as one single string -

sql server - Why does Linq-to-SQL add unnecessary COUNT()? -