4 ms·
"You don't need to be an expert! Much nicer than dealing with the minutiae of parallelism (threads, semaphores, locks, barriers, etc.)" Great! But then, a few
by martinced 14y ago
"You don't need to be an expert! Much nicer than dealing with the minutiae of parallelism (threads, semaphores, locks, barriers, etc.)"
Great! But then, a few slides later:
"Go has 'sync' and 'sync/atomic' packages that provides mutexes, condition variables, etc."
: (
Can program written in Go still deadlock or not? I became a big of Clojure's no-brainer "no locks at all, hence no deadlock" approach btw.
- jamesmiller5 14y agoThe packages are available but you don't need to use them and are often encouraged not to. Yes, you can still have all goroutines asleep and the program will halt but that's due to improper concurrent design rather than a program implementation mistake.
- voidlogic 14y agoGo just makes things easy to get right, it doesn't make you get them right. Mutexes, condition vars, atomic operations on primitives have their place. That place is usually in scenarios where channels do not fit well. A program written in Go can deadlock, but the runtime detects deadlock and terminates the program, so at a system level, it does not deadlock. P.S. "No locks at all, hence no deadlock", is this not true, any system with blocking operations can deadlock. You can construct a Go program that only uses channels and get it to deadlock...
- ominous_prime 14y agoYes, 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.
- kibwen 14y agoHow 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.
- jamesmiller5 14y agoThe 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.
- Djehngo 14y agoI assume every OS thread the go runtime is utilising is looking for an unblocked goroutine to execute and can't find any unblocked ones.
- lucian1900 14y agoIt is in the general case, but most cases are decidable, so it's still a useful feature.
- ridiculous_fish 14y agoThis 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!)
- ominous_prime 14y agoYes, 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%.
- jerf 14y agoGo has mutable variables by default, and channels can send pointers or other mutable values, such that two goroutines may be trying to modify them at once. Thus, mutexes can still be useful. This may go back to the fact Go is trying to be a systems language, so while it's not C(++) in terms of controlling memory layout and resources, it still has some constructs designed to give more control over the system than something like Erlang or Haskell does (at least in the "default" language subset). It is possible and indeed easy to do unsafe things in Go. It is not like Erlang or Haskell, in that you must still consider things like what goroutine "owns" a value without any particular language support or enforcement for that decision.