0

I am new to Go and also looked abit on the thread "throw: all goroutines are asleep", but I am still wondering why this piece of code deadlock. I believe that I put a number in namesInDir, and should be able to print it afterwards. It seems that I can not add the number to the channel - which confuses me. Anyone that can help me?

type uniprot struct
{
    namesInDir chan int
}


func main(){
u := uniprot{}
u.namesInDir = make(chan int)
u.namesInDir <- 1
//u.readFilenames(os.Args[1])
u.printName()
}   

func (u* uniprot) printName(){
    name := <-u.namesInDir
    fmt.Println(name)
}

I got some suggestion and that I could cheat by buffering the channel. Why is not this working?

u.namesInDir = make(chan int, 100)
u.namesInDir <- 1
for i := 0; i < 10; i++ {
    go u.printName()
}
stian
  • 1,947
  • 5
  • 25
  • 47

1 Answers1

3

Buffering the channel works like this.

A channel with no buffer blocks the sender until the receiver takes the value. In your original example you only have one go routine so all go routines are blocked when you send the integer. A buffer overcomes this. Alternatively run two go routines - one sending and one receiving.

package main

import "fmt"

type uniprot struct {
    namesInDir chan int
}

func (u *uniprot) printName() {
    name := <-u.namesInDir
    fmt.Println(name)
}

func main() {
    u := uniprot{}
    u.namesInDir = make(chan int, 1) // Buffer added here
    u.namesInDir <- 1
    //u.readFilenames(os.Args[1])
    u.printName()
}
Nick Craig-Wood
  • 52,955
  • 12
  • 126
  • 132
  • This is correct but it is good style to use *two* goroutines with the channel (as remarked above). Channels' purpose is as a synchronisation and communication primitive between goroutines. So although a buffered channel *can* work as a store within a *single* goroutine, there are more appropriate ways to do that. – Rick-777 Sep 30 '13 at 11:31