Patologias de Locks
O lock resolve a exclusão mútua, mas abre a porta pra uma classe nova de problemas. O contador sem sincronização dava resultado errado; os problemas deste capítulo são de outra natureza: o programa para de fazer progresso, ou faz uma thread esperar pra sempre. Nenhum deles corrompe dados. Eles travam ou emperram a execução.
Vale conectar os três com as propriedades que uma solução de exclusão mútua precisa garantir. Deadlock e livelock são falhas de progresso: em ambos, as threads deixam de avançar, num caso porque estão todas bloqueadas esperando umas às outras, no outro porque estão todas ocupadas reagindo umas às outras sem chegar a lugar nenhum. Starvation é uma falha de espera limitada: o programa como um todo progride, mas uma thread específica fica indefinidamente sem a sua vez.
Os três vêm de usar locks, e os três têm solução. A diferença entre saber usar um mutex e saber escrever código concorrente correto está, em boa parte, em reconhecer e evitar essas três patologias.