printing to the console inside a gorountine

2,836 views
Skip to first unread message

Nicolas Palumbo

unread,
Feb 2, 2012, 10:16:11 PM2/2/12
to golan...@googlegroups.com
Hello All,
I'm trying to write my own version of the sleeping barber problem
based on tannenbaum's book.

I want to print when the barber is "cutting hair" this may change
later to something else, I'd like to reach to a point where I kind
print Barber X is cutting hair to Customer Y. The problem that I'd
like to approach now is how to write content to the screen from a
gorountine? In the code below, if I remove the go statement from the
function, I can get content to the screen, but if I make it a
gorountine to run in the back, it does not print anything.

Any ideas? I know is quite basic, but I scanned Effective go for ir
and couldn't find anything specific.

This is what I have so far.

1 package main
2
3 import "fmt"
4
5 func main(){
6 //chBarbers:= make(chan int)
7 chCustomers:= make(chan int,1)
8 chMutex:= make(chan int,1)
9 //var waiting int = 0
10 fmt.Printf("HASD\n");
11
12 //chCustomers <- 1
13 //chMutex <- 1
14
15 go barber(chCustomers, chMutex);
16 }
17
18
19 func barber(chCustomers chan int , chMutex chan int ) {
20 for ;; {
21 // <- chCustomers
22 // <- chMutex
23 fmt.Printf("Cutting hair");
24 }
25
26 }

Thanks,
Nico

Adam Logghe

unread,
Feb 2, 2012, 10:34:14 PM2/2/12
to golan...@googlegroups.com
Probably your main function was exiting before the goroutine had a chance to run (there is no guarantee that goroutines will run if you dont block the main function), Also notice the directions that the items are entering or exiting the channels.

Notice how the main function now blocks waiting for something on chDone for everytime the barber cuts the hair.

package main

import "fmt"

func main() {
chCustomers := make(chan int, 1)
chDone := make(chan int, 1)
go barber(chCustomers, chDone)
chCustomers <- 1
chCustomers <- 1
chCustomers <- 1
<-chDone //this just pulls something of the channel and discards it
<-chDone
<-chDone
}

func barber(chCustomers chan int, chDone chan int) {
for {
<-chCustomers
fmt.Println("Cutting hair")
chDone <- 1
}

}

Enjoy Go!


Nigel Tao

unread,
Feb 2, 2012, 10:37:30 PM2/2/12
to Nicolas Palumbo, golan...@googlegroups.com
On 3 February 2012 14:16, Nicolas Palumbo <napa...@gmail.com> wrote:
> gorountine? In the code below, if I remove the go statement from the
> function, I can get content to the screen, but if I make it a
> gorountine to run in the back, it does not print anything.

A Go program exits when its main function returns. With the "go" at
line 15, you don't wait around long enough to let the barber goroutine
print, before the program exits.

You could add a time.Sleep(1 * time.Second) at line 16. Or, if you
want to wait forever, use:
select {}

Adam Logghe

unread,
Feb 2, 2012, 10:46:06 PM2/2/12
to golan...@googlegroups.com
My example has a dumb bug ...it works with 3 but not more. If you don't interleave(or make a buffered channel) the sending and receiving they deadlock.

package main

import "fmt"

func main() {
chCustomers := make(chan int, 1)
chDone := make(chan int, 1)
go barber(chCustomers, chDone)
chCustomers <- 1
<-chDone
chCustomers <- 1
<-chDone
chCustomers <- 1
<-chDone
chCustomers <- 1

Nicolas Palumbo

unread,
Feb 4, 2012, 11:30:52 PM2/4/12
to golan...@googlegroups.com
I think I got it working now for 5 customers and one barber. I know it
will work if I make the Barber a buffered channel of size 2 and
running 2 barber goroutines, but it will be sort of a mess. Is it
possible to know which barber is cutting which customer's hair? How do
I get that information from the channels?

I attached the current working code.

THanks,
Nico

sleepingBarber.go

Robert Bloomquist

unread,
Feb 5, 2012, 5:18:06 PM2/5/12
to golan...@googlegroups.com
Make the waiting room a channel of channel of ints.  The customer reserves his place in line by sending a channel of ints into the lobby waiting room, then sends his customer id on the channel he just sent.  The barber receives the channel, then reads the customer id from the channel he just received.  The barber cuts the customer's hair, and notifies then customer on the same channel.

Nicolas Palumbo

unread,
Feb 5, 2012, 9:54:49 PM2/5/12
to golan...@googlegroups.com
Looks good. I modified it to work with 2 barbers:

http://play.golang.org/p/tJj7rHmnxD

for ch, ok := <-lobby; ok ; ch, ok = <-lobby {

What is the meaning of the for above?

Adam Logghe

unread,
Feb 5, 2012, 10:36:26 PM2/5/12
to golan...@googlegroups.com
"""for ch, ok := <-lobby; ok ; ch, ok = <-lobby {

What is the meaning of the for above?"""

I think it's just a wordier version of - 

for ch:= range lobby{

This will work on items that arrive on the channel until you "close(lobby)" from the other end at which point the for loop will break.

Adam

John Asmuth

unread,
Feb 5, 2012, 10:43:47 PM2/5/12
to golan...@googlegroups.com


On Sunday, February 5, 2012 10:36:26 PM UTC-5, Adam Logghe wrote:
I think it's just a wordier version of - 

for ch:= range lobby{

Except that if it starts with a closed channel, it will do one iteration on an invalid ch before quitting. 

Adam Logghe

unread,
Feb 6, 2012, 12:02:04 AM2/6/12
to golan...@googlegroups.com
Hmmm that doesn't seem like correct behavior on first thought but thanks for pointing it out.

If it happens, it's probably me getting sloppy on the other side, but I'll have to keep an eye out for that...
Reply all
Reply to author
Forward
0 new messages