Simple Semaphore With a Buffered Channel in Go
You can pretty easily use buffered channels as a semaphore to simulate a worker pool in Go.
Buffered Channels
Let’s do a quick review of buffered channels.
- With unbuffered channels, both sends and receives block execution. They will only accept sends (
chan <-
) if there is a corresponding receive (<- chan
) ready to receive the sent value (source). - With a buffered channel, it will accept a number of values without a receiver waiting, up until the capacity of the buffer.
I found this example from Naveen Ramanathan to be very helpful (source here).
Example
To acquire the semaphore, you send to the buffered channel. To release the semaphore, you receive from the buffered channel.
The data actually stored in the buffered channel doesn’t really matter.
Then use it:
There is, however, a problem here. The semaphore constrains the number of goroutines that are doing the expensive thing at once, but it doesn’t make the main goroutine wait for all the worker goroutines to finish.
In fact if you watch the output gif closely, you’ll realize it doesn’t print out “Expensive thing done 18” (or 19).
Let’s fix that.
Wow! You read the whole thing. People who make it this far sometimes
want to receive emails when I post something new.
I also have an RSS feed.