Is it safe to read a function pointer concurrently without a lock?

天涯浪子 提交于 2019-11-26 15:30:20
icza

Unsynchronized, concurrent access to any variable from multiple goroutines where at least one of them is a write is undefined behavior by The Go Memory Model.

Undefined means what it says: undefined. It may be that your program will work correctly, it may be it will work incorrectly. It may result in losing memory and type safety provided by the Go runtime (see example below). It may even crash your program. Or it may even cause the Earth to explode (probability of that is extremely small, maybe even less than 1e-40, but still...).

This undefined in your case means that yes, i may be nil, partially assigned, invalid, undefined, ... anything other than either a or b. This list is just a tiny subset of all the possible outcomes.

Stop thinking that some data races are (or may be) benign or unharmful. They can be the source of the worst things if left unattended.

Since your code writes to the variable a in one goroutine and reads it in another goroutine (which tries to assign its value to another variable i), it's a data race and as such it's not safe. It doesn't matter if in your tests it works "correctly". One could take your code as a starting point, extend / build on it and result in a catastrophe due to your initially "unharmful" data race.

As related questions, read How safe are Golang maps for concurrent Read/Write operations? and Incorrect synchronization in go lang.

Strongly recommended to read the blog post by Dmitry Vyukov: Benign data races: what could possibly go wrong?

Also a very interesting blog post which shows an example which breaks Go's memory safety with intentional data race: Golang data races to break memory safety

In terms of Race condition, it's not safe. In short my understanding of race condition is when there're more than one asynchronous routine (coroutines, threads, process, goroutines etc.) trying to access the same resource and at least one is a writing operation, so in your example we have 2 goroutines reading and writing variables of type function, I think what's matter from a concurrent point of view is those variables have a memory space somewhere and we're trying to read or write in that portion of memory.

Short answer: just run your example using the -race flag with go run -race or go build -race and you'll see a detected data race.

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!