Golang concurrency: Difference between revisions

From wikinotes
Line 6: Line 6:
== Testing ==
== Testing ==
<blockquote>
<blockquote>
<syntaxhighlight lang="go">
<syntaxhighlight lang="bash">
go run -race foo.go  # run, checking for race conditions
go run -race foo.go  # run, checking for race conditions
</syntaxhighlight>
</syntaxhighlight>

Revision as of 20:17, 6 June 2022

This page is about the methods of concurrency provided by go.
If you're looking for synchronization primitives (ex. mutexes, semaphores, ... see golang synchronization)

Threading

Testing

go run -race foo.go  # run, checking for race conditions

Limits

Threads are a finite resource. You only have so many CPU cores, and CPU cores can only evaluate one thread at a time. Go defaults to allowing one thread per core, but you can generally get additional performance by increasing this.

require "runtime"

runtime.GOMAXPROCS(-1)  // show configured max-number of threads
runtime.GOMAXPROCS(2)   // set max-number of threads

Goroutines

TODO:

Is this really true? How are coroutines implemented?

Goroutines use green-threads rather than os-threads.
An OS thread is relatively expensive in setup and memory. One thread is reserved for a particular stack.
Go abstracts threads/threadpools with goroutines to make threads relatively cheap.

func doThing() {
    fmt.Println("hi")
}

func main() {
    go sayHello()  // <-- run in thread
}

Go functions default to using value objects rather than references.
Depending on your datastructure, this makes goroutines fairly concurrency-safe, since it operates on a copy of the data, rather than the same data.

func printThing(a string) {
    fmt.Println(a)
}


go printThing("abc")

OS Threads

I don't think golang exposes regular OS-threads.
At least, I can't find it it in the stdlib if it does.

Multiprocessing

There is no abstraction in go for distributing execution across multiple processes,
but goroutines execute on multiple cpu-cores at once, so it may not be needed.

If desired, you could implement it yourself with subprocesses glued together with some kind of IPC.