Does GOMAXPROCS(1) means run a program deterministically

625 views
Skip to first unread message

Ting Yuan

unread,
Nov 2, 2020, 12:14:42 AM11/2/20
to golang-nuts

I find it is tricky to debug a concurrency Go program in multi-core systems, so I wonder if there is a way to make the program run in deterministically. Can I assume a program with GOMAXPROCS(1) can be deterministically executed ?

Here a deterministic execution means once the input is given, the execution of the prorgam is serialized. Every instruction in the execution follows a certain order unless the input is changed.

Harald Weidner

unread,
Nov 2, 2020, 2:31:59 AM11/2/20
to Ting Yuan, golang-nuts
Hello,

> I find it is tricky to debug a concurrency Go program in multi-core
> systems, so I wonder if there is a way to make the program run in
> deterministically. Can I assume a program with GOMAXPROCS(1) can be deterministically
> executed ?

Even with GOMAXPROCS=1, a Go program is not 100% deterministic. See this
funny blog post on how to gain randomness even without using the standard
library.
https://blog.merovius.de/2018/01/15/generating_entropy_without_imports_in_go.html

Using libs, there are even more sources of indeterminism, e.g. time.Now()
or both of the "rand" packages.

Best regards,
Harald

Kurtis Rader

unread,
Nov 2, 2020, 12:52:54 PM11/2/20
to Ting Yuan, golang-nuts
On Sun, Nov 1, 2020 at 9:15 PM Ting Yuan <yuan...@ict.ac.cn> wrote:
I find it is tricky to debug a concurrency Go program in multi-core systems, so I wonder if there is a way to make the program run in deterministically. Can I assume a program with GOMAXPROCS(1) can be deterministically executed ?

In addition to Harald's answer I'll point out you should be running your unit tests with race detection enabled. If you don't have good test coverage you may want to enable race detection in your binary. See https://golang.org/doc/articles/race_detector.html 

--
Kurtis Rader
Caretaker of the exceptional canines Junior and Hank

Axel Wagner

unread,
Nov 2, 2020, 1:34:15 PM11/2/20
to Kurtis Rader, Ting Yuan, golang-nuts
Hi,

another thing to keep in mind is that `GOMAXPROCS=1` does not actually make your program single-threaded:

The GOMAXPROCS variable limits the number of operating system threads that can execute user-level Go code simultaneously. There is no limit to the number of threads that can be blocked in system calls on behalf of Go code; those do not count against the GOMAXPROCS limit.
 

So, as long as your program uses blocking syscalls (the overwhelming majority of Go programs do), the runtime will still spawn multiple threads. So if you have, say, multiple Goroutines that read from files, the order in which the `Read` calls return is probably non-deterministic.

FWIW, the playground used to be completely deterministic. Recently it started using gVisor though and I don't know how deterministic this new runtime is. But with a sufficiently old Go version you can get deterministic execution by compiling to NaCl.

--
You received this message because you are subscribed to the Google Groups "golang-nuts" group.
To unsubscribe from this group and stop receiving emails from it, send an email to golang-nuts...@googlegroups.com.
To view this discussion on the web visit https://groups.google.com/d/msgid/golang-nuts/CABx2%3DD-khBVjC6Kg3NRi6DLYxHsX9wSX3u5NT_tgeNP-CK3bcA%40mail.gmail.com.

Brian Candler

unread,
Nov 2, 2020, 3:26:36 PM11/2/20
to golang-nuts
I'd also assume that `GOMAXPROCS=1` doesn't disable the preemptive scheduling of goroutines in recent Go versions - I believe `GODEBUG=asyncpreemptoff=1` is required for that.

Reply all
Reply to author
Forward
0 new messages