Hacker Newsnew | past | comments | ask | show | jobs | submitlogin

Yes, you can still deadlock, but the runtime will usually panic saying that no goroutines can advance, which is definitely nicer than just hanging. If the core of your code is synchronized on channels, it becomes very easy to manage.


This is indeed a nice feature, but it's worth pointing out that if any goroutine can make progress, the deadlock will be missed.

For example, if you launched a task to do some work in the background, and the task deadlocks with one of its own goroutines or even itself (e.g. reads and writes on the same channel), this deadlock will not be reported.

In a large system with many goroutines, I think it is more likely to have a deadlock within a component instead of process-wide, and these will not be reported. (Yet!)


Yes, I should have emphasized "usually".

I also locked up a program by inadvertently creating a small goroutine with a busy-loop (the typo being time.Sleep(1)). That little loop prevented any other goroutines from getting scheduled, though it wasn't hard to deduce what was happening, since the CPU was running at 100%.


How does the runtime detect this? I'd have suspected that such a thing would be undecidable, but I'm not at all a concurrency expert.


The run-time checks if all goroutines are asleep and waiting for input. If true it panics and halts the program.

It can't detect live-lock or thrashing, if you are still waking up other goroutines but not doing anything useful it won't prevent that.


I assume every OS thread the go runtime is utilising is looking for an unblocked goroutine to execute and can't find any unblocked ones.


It is in the general case, but most cases are decidable, so it's still a useful feature.




Guidelines | FAQ | Lists | API | Security | Legal | Apply to YC | Contact

Search: