Go 工具链详解(五):竞态条件检测神器 Race Detector

2023-09-14 22:20:31

并发编程可以提高程序的性能和稳定性,但也带来了一些挑战,如竞态条件。竞态条件是指并发程序中的多个线程同时访问共享资源,导致程序行为不确定的问题。为了避免竞态条件的产生,需要使用同步机制(如互斥锁、条件变量等)来协调线程之间的访问。然而,在复杂的程序中,竞态条件可能难以察觉,因此 Golang 提供了竞态条件检测工具 Race Detector。

Race Detector 的原理

race detector 集成在了 golang 的工具链中,当设置了 -race 标志位时,编译器会使用代码记录所有的内存访问,包括访问内存的时间和方式,而运行时库则监控对共享变量的不同步访问情况。当检测到这种竞态行为时,将会打印警告信息。

因为 race detector 只有在代码运行起来并且竞争条件被触发后才能检测到,所以需要在实际工作负载状态下进行检测,但是开启竞态条件检测会占用10倍的 CPU 和内存,因此在生产环境进行是不太现实的,所以推荐在负载测试或者集成测试阶段进行竞态条件检测(也可以在生产环境中部署多个实例,其中一个实例开启竞态条件检测)。

Race Detector 使用方法

Race Detector 的使用方法也非常简单,因为 race detector 集成在了 golang 的工具链中,编译时如果要开启竞态条件检测,只需在命令行中添加 -race 标志即可。例如:

$ go test -race mypkg    // 测试包
$ go run -race mysrc.go  // 编译并运行
$ go build -race mycmd   // 编译
$ go install -race mypkg // 安装包

看一个具体的示例,代码如下:

package main

import "fmt"

func main() {
    done := make(chan bool)
    m := make(map[string]string)
    m["name"] = "world"
    go func() {
        m["name"] = "data race"
        done <- true
    }()
    fmt.Println("Hello,", m["name"])
    <-done
}

使用如下命令进行竞态条件检测:

$ go run -race racy.go
Hello, world
==================
WARNING: DATA RACE
Write at 0x00c0000940c0 by goroutine 6:
  runtime.mapassign_faststr()
      /usr/local/go1.21/src/runtime/map_faststr.go:203 +0x0
  main.main.func1()
      /Users/路多辛的博客/projects/go/workspace/hello/racy.go:10 +0x4a

Previous read at 0x00c0000940c0 by main goroutine:
  runtime.mapaccess1_faststr()
      /usr/local/go1.21/src/runtime/map_faststr.go:13 +0x0
  main.main()
      /Users/路多辛的博客/projects/go/workspace/hello/racy.go:13 +0x159

Goroutine 6 (running) created at:
  main.main()
      /Users/路多辛的博客/projects/go/workspace/hello/racy.go:9 +0x13c
==================
==================
WARNING: DATA RACE
Write at 0x00c0000ac088 by goroutine 6:
  main.main.func1()
      /Users/路多辛的博客/projects/go/workspace/hello/racy.go:10 +0x56

Previous read at 0x00c0000ac088 by main goroutine:
  main.main()
      /Users/路多辛的博客/projects/go/workspace/hello/racy.go:13 +0x164

Goroutine 6 (running) created at:
  main.main()
      /Users/路多辛的博客/projects/go/workspace/hello/racy.go:9 +0x13c
==================
Found 2 data race(s)
exit status 66

小结

race detector 是一个用于检查并发逻辑正确性的强大工具,不会误报,所以一定要认真解决检测出的问题。代码被执行到的越多也就是代码覆盖率越高,检测效果越好。通过合理使用 race detector,可以提高并发程序的质量和稳定性。

更多推荐

Linux(Centos)查看硬盘大小

Linux查看硬盘大小使用df命令:df命令可以用来显示文件系统的磁盘使用情况,包括每个挂载点的磁盘空间大小和使用情况。要查看硬盘大小,可以运行以下命令:df-h这将以人类可读的方式显示文件系统的磁盘大小,以GB或MB为单位。下面是df-h命令输出的参数说明:Filesystem:文件系统的名称或挂载点。这是磁盘空间的

Delft3D水动力与泥沙运动模拟实践应用

水体中泥沙运动是关系到防洪,调水等方面的重要问题,也是水利和水环境领域科研热点之一。水利数值模型,在环境影响评价、防洪规划等方面也有着广泛的应用。荷兰Delft研究所开发的Delft3D模型是世界上最先进的水动力之一,能够运用于河网、浅水湖泊、深水水库以及近岸海洋等多种水体的水动力和泥沙问题的研究中;同时,Delft3

MYSQL数据库基础

这里写目录标题MYSQL数据库基础一.数据库原理1.数据的时代2.数据库的发展史1)文件管理系统的缺点2)数据库系统发展阶段3)DBMS数据库管理系统4)数据库管理系统的优点5)数据库管理系统的基本功能6)数据库系统的架构7)各种数据库管理系统8)关系型数据库理论二.MYSQL历史关系型数据库和非关系型数据库三.mys

【Vue】路由与Node.js下载安装及环境配置教程

🎉🎉欢迎来到我的CSDN主页!🎉🎉🏅我是Java方文山,一个在CSDN分享笔记的博主。📚📚🌟推荐给大家我的专栏《Vue快速入门》。🎯🎯👉点击这里,就可以查看我的主页啦!👇👇Java方文山的个人主页🎁如果感觉还不错的话请给我点赞吧!🎁🎁💖期待你的加入,一起学习,一起进步!💖💖目录前言

访问学者申请一定要会说英语吗?

访问学者申请一定要会说英语吗?显然,出国做访问学者,外语是出国的关键,这是毋庸置疑,而且必须严格对待的。下面就随知识人网小编一起来深入探讨一下。首先,我们需要明确的是,访问学者申请通常要求申请者具备一定的英语能力。这是因为访问学者在国外学术机构或大学进行研究工作时,需要与导师、同事以及学生进行有效的沟通,而英语通常是国

go工具类的封装——(一)配置文件工具类封装

使用方式在后端开发中,我们经常会使用配置文件,所以我想封装出一个工具类出来,能够提供简洁的接口,让我们很方便地读取配置文件并从配置文件中提取信息。我封装了一个工具类ConfigManager,主要有以下功能:根据配置文件的路径和文件名读取配置信息通过一系列Get函数,可以根据key查询配置项的值自动将配置项写入缓存,提

Python Subprocess介绍:基础和示例

PythonSubprocess介绍:基础和示例探索PythonSubprocess模块的逐步指南,包括示例。目录什么是PythonSubprocess何时使用PythonSubprocessPythonSubprocess示例PythonSubprocess管道结论PythonSubprocess常见问题什么是Pyt

数据结构--哈希表,哈希函数(或者散列表、散列函数)

目录哈希表的定义处理冲突的方法--拉链法散列查找常见的散列函数(构造哈希函数)除留余数法直接定址法数字分析法平方取中法处理冲突的方法--开放定址法(1)线性探测法:(2)平方探测法(3)伪随机序列发处理冲突的方法--再散列法总结哈希表的定义处理冲突的方法--拉链法散列查找圈出来部分,分别是除了第一层查找1次,其他每个元

【算法】二分答案

文章目录相关链接什么时候使用二分答案?题目列表最大化最小化相关题目列表📕2439.最小化数组中的最大值解法1——二分答案解法2——分类讨论O(n)2513.最小化两个数组中的最大值(二分答案+lcm+容斥原理)🐂好题!相似题目(容斥原理+二分查找)878.第N个神奇数字1201.丑数III2517.礼盒的最大甜蜜度

Golang并发的循环

本节中,我们会探索一些用来在并行时循环迭代的常见并发模型。我们会探究从全尺寸图片生成一些缩略图的问题。gopl.io/ch8/thumbnail包提供了ImageFile函数来帮我们拉伸图片。我们不会说明这个函数的实现,只需要从gopl.io下载它。gopl.io/ch8/thumbnailpackagethumbna

爬虫使用代理IP不会被限的原因解析

在网络爬虫的世界中,使用代理IP可以为您带来许多好处,其中之一就是能够避免被目标网站限制或封锁。本文将解析爬虫使用代理IP不会被限的原因,帮助您突破封锁,高效抓取所需数据!IP匿名性:代理IP可以隐藏爬虫程序的真实IP地址,使目标网站无法准确获取您的真实身份和位置信息。目标网站通常会根据IP地址进行访问限制或封锁,尤其

热文推荐