I have recently written decillion/go-stm, which is a software transactional memory (STM) implementation for Go. It provides a new way of synchronization to Go programmers, while it is still experimental one.
The package enables one to atomically execute a sequence of operations on shared variables without explicit locking. I present a simple example below. Please see the repository or a blog post (in Japanese) for further information.
// Initialize two transactional variables.
x := New(0)
y := New(0)
// Define a transaction that transfer 100 from x to y.
transfer := func(rec *TRec) interface{} {
currX := rec.Load(x).(int) // Read the value of x.
currY := rec.Load(y).(int) // Read the value of y.
rec.Store(x, currX-100) // Write currX-100 to x.
rec.Store(y, currY+100) // Write currY-100 to y.
return nil
}
// Execute the transaction atomically.
Atomically(transfer)
If you want to know more about the STM itself, I recommend you to read the article, Beautiful concurrency, written by Simon Peyton Jones.
There has been another STM package written by lukechampine. It provides a richer STM interface but is less performant than the present package. Here is the result of a very simple benchmark, in which two transactional variables are atomically incremented or read. The benchmark is taken at Ubuntu 17.10 on a DigitalOcean's High CPU Droplet with 32 cores.
Benchmark_Read90Write10_decillion-4 10000000 156 ns/op
Benchmark_Read90Write10_decillion-8 10000000 144 ns/op
Benchmark_Read90Write10_decillion-16 10000000 214 ns/op
Benchmark_Read90Write10_decillion-32 5000000 289 ns/op
Benchmark_Read90Write10_lukechampine-4 2000000 761 ns/op
Benchmark_Read90Write10_lukechampine-8 2000000 822 ns/op
Benchmark_Read90Write10_lukechampine-16 2000000 912 ns/op
Benchmark_Read90Write10_lukechampine-32 2000000 966 ns/op
Top comments (0)