I'm trying to ensure that my concurrent program is free of the following,
I found the following tool http://blog.golang.org/race-detector
And I tried compiling and running using -race
enabled and did not see any complaints.
Does anyone know whether this checks for all the above issues? Does not receiving any complaints in the output mean to say that the program is free of these issues?
Deadlock, livelock and starvation cannot be eliminated by testing alone and they are not detected by the Go race detector. Deadlocks in Go programs will be detected at runtime, but then it's usually too late. Livelocks (non-terminating busy loops) will not be detected unless they also cause a deadlock.
Thread starvation is similar to livelock in that imbalanced busy-ness in an application causes some activities to be stymied and never make the expected progress. An example is the famous 'Wot no Chickens?' by Peter Welch.
The race detector itself is limited in its usefulness because some race conditions depend on environment and the conditions that cause a particular race may be absent during the testing phase, so the race detector will miss them.
If all this sounds rather bleak, there is a body of theoretical work that can help a lot. The premise is that these four dynamic problems are best addressed via design strategies and language features, rather than by testing. As a simple example, the Occam programming language (which is quite like Go in its concurrency model) has a parallel usage rule enforced by the compiler that eliminates race conditions. This imposes a restriction on the programmer: aliases for mutable state (i.e. pointers) are not allowed.
Thread starvation in Go (and Occam) should likewise not be as much a problem as in Java because the concurrency model is better designed. Unless you abuse select
, it won't be a problem.
Deadlock is best addressed by theoretically-based design patterns. For example, Martin & Welch published A Design Strategy for Deadlock-Free Concurrent Systems, which described principally the client-server strategy and the i/o-par strategy. This is aimed at Occam programs but applies to Go as well. The client-server strategy is simple: describe your Go-routine network as a set of communicating servers and their clients; ensure that there are no loops in the network graph => deadlock is eliminated. I/o-par is a way to form rings and toruses of Go-routines such that there will not be a deadlock within the structure.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With