dou7851 2016-12-06 09:28
浏览 41
已采纳

Go的种族探测器如何知道锁?

Adding lock to a program with race condition can solve the race condition and make the race detector quiet. How can Go's race detector be aware of lock?

Someone points out that "the race detector can only detect race conditions if and when they actually occur".

Consider the following program:

package main

import (
    "sync"
    "time"
)

func main() {
    var a int
    var wg sync.WaitGroup
    workers := 2
    wg.Add(workers)
    for i := 1; i <= workers; i++ {
        go func(sleep int) {
            time.Sleep(time.Duration(sleep) * time.Second)
            a = 1
            wg.Done()
        }(i * 5)
    }
    wg.Wait()
}

One goroutine sleeps for 5 seconds, another sleeps for 10 seconds, they don't write a at the same time in most cases, but the race detector prints the race condition warning every time. Why?

  • 写回答

2条回答 默认 最新

  • douye8500 2016-12-06 09:48
    关注

    The race detector does not analyze the source code, it doesn't know that you added locks in the source code.

    The race detector works at runtime:

    When the -race command-line flag is set, the compiler instruments all memory accesses with code that records when and how the memory was accessed, while the runtime library watches for unsynchronized accesses to shared variables.

    Because of this design, the race detector can only detect race conditions if and when they actually occur. So when you add proper locking / synchronization, the race condition will not happen (the if condition will not be met), and so no warning will be printed.

    See this blog post for more details: Introducing the Go Race Detector

    And this article: Data Race Detector

    Edit for your example:

    It may be that your 2 goroutines will never reach the point where they write the shared variable a at the same physical time (because the code runs so fast and the sleep time is relatively huge), but they run concurrently, in different goroutines, without explicit synchronization (a synchronization point may be channel communication, mutex lock/unlock etc.).

    The race condition does not imply that access to a shared variable does happen at the same time (one of which must be a write). The race condition is also met if access to a shared variable happens concurrently (from multiple goroutines), without synchronization. This can be detected at runtime by the race detector (due to the instrumented memory access code).

    Code generated by the compiler is allowed to use cached instances of the a variable in multiple goroutines, the runtime only has to guarantee that the cached instances are "refreshed" or disposed of if a synchronization point is reached. For details, see The Go Memory Model.

    Also note that time.Sleep() does not guarantee that execution will continue right after the specified duration, only that execution will be suspended for at least the specified duration (so the execution may continue at a later time):

    Sleep pauses the current goroutine for at least the duration d.

    本回答被题主选为最佳回答 , 对您是否有帮助呢?
    评论
查看更多回答(1条)

报告相同问题?

悬赏问题

  • ¥15 使用C#,asp.net读取Excel文件并保存到Oracle数据库
  • ¥15 C# datagridview 单元格显示进度及值
  • ¥15 thinkphp6配合social login单点登录问题
  • ¥15 HFSS 中的 H 场图与 MATLAB 中绘制的 B1 场 部分对应不上
  • ¥15 如何在scanpy上做差异基因和通路富集?
  • ¥20 关于#硬件工程#的问题,请各位专家解答!
  • ¥15 关于#matlab#的问题:期望的系统闭环传递函数为G(s)=wn^2/s^2+2¢wn+wn^2阻尼系数¢=0.707,使系统具有较小的超调量
  • ¥15 FLUENT如何实现在堆积颗粒的上表面加载高斯热源
  • ¥30 虚心请教几个问题,小生先有礼了
  • ¥30 截图中的mathematics程序转换成matlab