concurrency safety

268 views
Skip to first unread message

Alexey Dvoretskiy

unread,
Nov 25, 2020, 9:13:56 PM11/25/20
to golang-nuts
How would you cal "thread-safety" in Go? Go doesn't have threads so the term "thread-safety" sounds bit off.

Kurtis Rader

unread,
Nov 25, 2020, 9:20:39 PM11/25/20
to Alexey Dvoretskiy, golang-nuts
On Wed, Nov 25, 2020 at 6:13 PM Alexey Dvoretskiy <advor...@emeraldcloudlab.com> wrote:
How would you cal "thread-safety" in Go? Go doesn't have threads so the term "thread-safety" sounds bit off. 

Some more context around your question would be helpful. Personally, I don't see a problem with "thread-safe" in the context of Go but you could also say "concurrency-safe".

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

Ian Lance Taylor

unread,
Nov 25, 2020, 9:55:06 PM11/25/20
to Alexey Dvoretskiy, golang-nuts
On Wed, Nov 25, 2020 at 6:13 PM Alexey Dvoretskiy
<advor...@emeraldcloudlab.com> wrote:
>
> How would you cal "thread-safety" in Go? Go doesn't have threads so the term "thread-safety" sounds bit off.

The standard library says things like "Multiple goroutines may invoke
methods on a Conn simultaneously" (from
https://golang.org/pkg/net/#Conn).

Terms like "thread safety" can come with various caveats and
restrictions, so it's usually best to avoid just saying "thread safe"
in general purpose documentations. Better to try to say more
precisely what is and what is not supported.

Ian

Øyvind Teig

unread,
Nov 27, 2020, 5:32:11 AM11/27/20
to golang-nuts
Thread safety, concurrency safety, goroutines safety. The same stuff to me.  

It's important that concurrent goroutines don't interfere with each other in such a way that internal state is compromised by other goroutines. Typically through access to internal data, through pointers. If only go channels are used to communicate between goroutines, than that case is closed. That's one of the reasons they exist - also in other similar languages, with that aspect often based on CSP.

But then, goroutines may communicate in a circle, the smallest would be two sending to each other and awaiting answer from each other at the "same" time. A system would easily freeze from this point and out. This would cause deadlock, which is pathological. Using deadlock free patterns may solve that problem from the beginning, provided such a pattern is used correctly. 

Finally(?), one goroutine could be busy by itself, or by communicating with others, so that it is not able to read vital messages from other goroutines, ever. This would be a livelock. 

I think go comes with a tool [1] that would help for some of these types of problems. I have not tested it myself, since I use another, embedded concurrent language. But I do read these mail lists every time they come, so I try to learn what this community is up to.

There would be ways whereby one could model concurrent programs as well. Lots of modelling languages exist. Myself I have to some extent used CSPm (with the FDR tool), FSP (with the LTSA tool) and Promela (with the Spin tool).

b.ca...@pobox.com

unread,
Nov 27, 2020, 6:19:11 AM11/27/20
to golang-nuts
On Friday, 27 November 2020 at 10:32:11 UTC oyvin...@teigfam.net wrote:
Thread safety, concurrency safety, goroutines safety. The same stuff to me.  

It's important that concurrent goroutines don't interfere with each other in such a way that internal state is compromised by other goroutines. Typically through access to internal data, through pointers.

Not just that, but also:

-  any global variables.  Even reading an 'int' while some other goroutine is updating it is unsafe; it may give undefined behavior.

- concurrent read and write accesses to the same map or slice can cause the program to panic.  Note that map and slice values contain hidden pointers inside them.  So if two goroutines have the same map or slice value, they are aliasing to the same underlying data.

These can trip up people used to (say) Python, where such accesses are atomic - primarily because of Python's Global Interpreter Lock.

(There is sync.Map which is concurrency-safe, but if you need this, there's probably a better solution in your architecture)
 
If only go channels are used to communicate between goroutines, than that case is closed. That's one of the reasons they exist - also in other similar languages, with that aspect often based on CSP.

Here's a video explaining how channels can replace various concurrency primitives: it's worth getting your head around.

Øyvind Teig

unread,
Nov 27, 2020, 11:00:26 AM11/27/20
to golang-nuts
Great! I liked Mill's lecture. After having seen it, here's my favourite:

Clojure core.async, lecture (45 mins). Rich Hickey discusses the motivation, design and use of the Clojure core.async library. He also talks about go. See https://www.infoq.com/presentations/clojure-core-async/ (lecture 22Nov2013) and https://clojure.org/news/2013/06/28/clojure-clore-async-channels (description).  Additionally you can download the soundtrack from this as an mp3.
Minutes into the lecture:
13.57 - CSP background
18.24 - The difference between blocking and parking. Also about IOC threads (Inversion of Control threads)
19.12 - The description of the difference between blocking and parking 

About blocking, I have a blog note myself: https://www.teigfam.net/oyvind/home/technology/092-not-so-blocking-after-all/ - Disclaimer: no money, ads, gifts in my blog notes. Only fun and expenses. 

Reply all
Reply to author
Forward
0 new messages