I am working with Milind to fix the data race in Uber's Go database. Here is the common data races concluded from his paper: "A Study of Real-World Data Races in Golang".
Pattern 1: Loop variable capture by reference.
In Go, the loop iterator variable in for range
is a single variable that takes different values in each loop iteration. (Loop variable capture by reference.)
It's better to make a local copy when using goroutines to process the loop variables.
Pattern 2: Error variable capture
Mixed use of error variable. In the following example, the concurrent writes on the return error variable from foo2()
and foo3()
cause a data race.
Pattern 3: Normal return in a function with a named return
In Go, there is a feature called "named result parameters". The return variable can be given names and used as regular variables, just like the incoming parameters. When named, they are initialized to the zero values for their types when the function begins; if the function executes a return
statement without arguments, the current values of the result parameters are used as the returned values.
Pattern 4: Deferred functions in a named return
Go offers a keyword defer
to schedule a function call (the deferred function) to be run immediately before the function executing the defer
returns.
Pattern 5: Meta fields of Slice change
The append
operation appends the elements to the slice's end and returns the result. The slice may change as the number of elements reaches the slice's length, which returns a new slice.
Pattern 6: Data Races on Thread-Unsafe Map
In Go, a map (hash table) is a sparse data structure, and accessing one element might result in accessing another element; if during the same process another insertion/deletion happens, it will modify the sparse data structure and cause a data race.
Pattern 7: Incorrect use of synchronization constructs
Incorrect use of synchronization constructs such as sync.Mutex
and sync.RWMutex
, which are value types (structures) in Go, often causes data races.
In the following example, the mutex passed to the two goroutines is captured by value. The two goroutines possess different mutex objects sharing no internal state. A correct implementation should pass the address of mutex (&mutex
).
Pattern 8: Mixing Shared Memory with Message Passing
Pattern 9: Incorrect Use of Flexible Group Synchronization
Go offers more leeway in its group synchronization construct sync.WaitGroup
. The number of participants is dynamic. Incorrect placement of Add
and Done
methods of a sync.WaitGroup
leads to data races.
In the following example, the incorrect placement of wg.Add(1)
fails to guarantee the racyAccess
is accessed before reaching wg.Wait()
.
Also, there is an example of incorrect placement of wg.Done()
.
Pattern 10: Mutating Shared Data in a Reader-Lock-Protected Critical Section
Go offers a reader-writer lock RWMutex
, which allows concurrent readers to execute a critical section simultaneously. The RLock/RUnlock
methods on an RWMutex
hold the lock in a read-only mode. Sometimes developers accidentally put statements that may modify shared data in critical sections protected by RWMutex
, while using RLock/RUnlock
methods.
Reference:
Chabbi, Milind, and Murali Krishna Ramanathan. "A study of real-world data races in Golang." Proceedings of the 43rd ACM SIGPLAN International Conference on Programming Language Design and Implementation. 2022.
最新评论
感谢博主,让我PyTorch入了门!
博主你好,今晚我们下馆子不?
博主,你的博客用的哪家的服务器。
您好,请问您对QNN-MO-PYNQ这个项目有研究吗?想请问如何去训练自己的数据集从而实现新的目标检测呢?
where is the source code ? bomb1 188 2 8 0 0 hello world 0 0 0 0 0 0 1 1 9?5
在安装qemu的过程中,一定在make install 前加入 sudo赋予权限。
所以作者你是训练的tiny-yolov3还是yolov3...
很有用