This repo implements examples and exercises from Allen B. Downey’s The Little Book of Semaphores.
Why?!! some would cry. Go has wonderful concurrency support, quite deliberately omitting semaphores. Why try to pound square pegs into round holes?
My first answer is that the book has tons of exercises that look fun, interesting, and challenging. These drew me in when I first found this book. I tried my hand at a few of them, had some fun, but soon grew frustrated at assumptions that seemed baked into the book’s solutions. I had to set it aside for a while.
Another answer is that it is in fact possible to implement semaphores in Go, just as the book describes, and therefore implement the solutions provided in the book, just as presented. A technical feat perhaps, but far from idiomatic Go.
So then, given one of these semaphore-based solutions in Go, how can it be simplified? Is there a drop-in Go language or standard library replacement for a given semaphore-based technique?
When simplifications run into assumptions, things get squishy. Is it fair to change he problem? In the interest of doing something interesting with concurrency, I think so.
Finally, I think a lot of these problems get more interesting when incorporated into some sort of a simulation. The book typically stops short of specifying such a simulation. I find them enlightening and satisfying though and have some fun wrting them. More often than not, the exercise of writing a simulation points out yet more tacit assumptions of the original problem description. Often assumptions about the physical world, or of agency or sentience of actors involved.
This is a git repo, a directory tree of files consisting of some runnable code and some documentation. The documentation is often text in AsciiDoc format (like this readme) and might offer a wide range of comments on why the code is written the way it is, or occassionally just comments on something from the book.
The naming and structure of the directory tree generally follows the chapters and sections of the book. There is just one importable Go package, "sem", at the top of the directory tree. Otherwise code is all runnable programs.
I try to implement most of Downey’s solutions from the book and implement them
as literally as possible using a semaphore implementation from the sem package.
The semaphore implementation I currently trust is the one based on Go channels
and so for most sections the first solution presented is implemented in a Go
source file called book.go
.
Other implmentations will have somewhate descriptive file names.
The readme for each section will have a heading for each program in the directory, saying something about it and giving example output. Code is not generally copied or quoted in the readme; the code is right there in the repo.
Downey typically gives a list of syncronization variables as his "hint" for solving the problem. As a convention I will try to keep these in a separate parenthesized variable declaration. So for example where Downey has
n = the number of threads count = 0 mutex = Semaphore (1) barrier = Semaphore (0)
my Go code will read
var ( n = 5 count = 0 mutex = sem.NewChanSem(1, 1) barrier = sem.NewChanSem(0, 1) )
January, 2018, I’m just putting up the first content. I have a little start on it, I have a number of these problems that I’ve toyed with in the past but long since lost my code. It will be a work in progress.
Other gophers have tried this before me!
Try a search like https://github.com/search?l=Go&q=little+book+of+semaphores&type=Repositories&utf8=%E2%9C%93 for example.