golang中的race检测

由于golang中的go是非常方便的,加上函数又非常容易隐藏go。

所以很多时候,当我们写出一个程序的时候,我们并不知道这个程序在并发情况下会不会出现什么问题。

所以在本质上说,goroutine的使用增加了函数的危险系数论go语言中goroutine的使用。比如一个全局变量,如果没有加上锁,我们写一个比较庞大的项目下来,就根本不知道这个变量是不是会引起多个goroutine竞争。

官网的文章Introducing the Go Race Detector给出的例子就说明了这点:

package main

import(
"time"
"fmt"
"math/rand"
) func main() {
start := time.Now()
var t *time.Timer
t = time.AfterFunc(randomDuration(), func() {
fmt.Println(time.Now().Sub(start))
t.Reset(randomDuration())
})
time.Sleep(5 * time.Second)
} func randomDuration() time.Duration {
return time.Duration(rand.Int63n(1e9))
}

这个例子看起来没任何问题,但是实际上,time.AfterFunc是会另外启动一个goroutine来进行计时和执行func()。

由于func中有对t(Timer)进行操作(t.Reset),而主goroutine也有对t进行操作(t=time.After)。

这个时候,其实有可能会造成两个goroutine对同一个变量进行竞争的情况。

这个例子可能有点复杂,我们简化一下,使用一个更为简单的例子:

package main

import(
"time"
"fmt"
) func main() {
a := 1
go func(){
a = 2
}()
a = 3
fmt.Println("a is ", a) time.Sleep(2 * time.Second)
}

在上面的例子中,看代码,我们其实看的出来,这里的go func触发的goroutine会修改a。

主goroutine 也会对a进行修改。但是我们如果只go run运行,我们可能往往不会发现什么太大的问题。

runtime  go run race1.go
a is 3

可喜的是,golang在1.1之后引入了竞争检测的概念。我们可以使用go run -race 或者 go build -race 来进行竞争检测。

golang语言内部大概的实现就是同时开启多个goroutine执行同一个命令,并且纪录每个变量的状态。

如果用race来检测上面的程序,我们就会看到输出:

runtime  go run -race race1.go
a is 3
==================
WARNING: DATA RACE
Write by goroutine 5:
main.func·001()
/Users/yejianfeng/Documents/workspace/go/src/runtime/race1.go:11 +0x3a Previous write by main goroutine:
main.main()
/Users/yejianfeng/Documents/workspace/go/src/runtime/race1.go:13 +0xe7 Goroutine 5 (running) created at:
main.main()
/Users/yejianfeng/Documents/workspace/go/src/runtime/race1.go:12 +0xd7
==================
Found 1 data race(s)
exit status 66

这个命令输出了Warning,告诉我们,goroutine5运行到第11行和main goroutine运行到13行的时候触发竞争了。

而且goroutine5是在第12行的时候产生的。

这样我们根据分析这个提示就可以看到这个程序在哪个地方写的有问题了。

当然这个参数会引发CPU和内存的使用增加,所以基本是在测试环境使用,不是在正式环境开启。

golang中的race检测的更多相关文章

  1. Golang中的自动伸缩和自防御设计

    Raygun服务由许多活动组件构成,每个组件用于特定的任务.其中一个模块是用Golang编写的,负责对iOS崩溃报告进行处理.简而言之,它接受本机iOS崩溃报告,查找相关的dSYM文件,并生成开发者可 ...

  2. golang中锁mutex的实现

    golang中的锁是通过CAS原子操作实现的,Mutex结构如下: type Mutex struct {     state int32                     sema  uint ...

  3. golang中的反射reflect详解

    先重复一遍反射三定律: 1.反射可以将"接口类型变量"转换为"反射类型对象". 2.反射可以将"反射类型对象"转换为"接口类型变量 ...

  4. golang 中 sync.Mutex 的实现

    mutex 的实现思想 mutex 主要有两个 method: Lock() 和 Unlock() Lock() 可以通过一个 CAS 操作来实现 func (m *Mutex) Lock() { f ...

  5. iOS中使用 Reachability 检测网络

    iOS中使用 Reachability 检测网络 内容提示:下提供离线模式(Evernote).那么你会使用到Reachability来实现网络检测.   写本文的目的 了解Reachability都 ...

  6. 浅谈JavaScript中的能力检测

    引言 我们知道,各个版本的浏览器有着许多不一致性.理想状态下,应该是所有的浏览器都提供一套标准的API接口.但是现实中,各个版本的浏览器存在的怪癖非常多,我们通常都是使用客户端检测来作为补救措施.但是 ...

  7. 基础知识 - Golang 中的正则表达式

    ------------------------------------------------------------ Golang中的正则表达式 ------------------------- ...

  8. AndroidPN中的心跳检测

    在AndroidPN客户端里存在着心跳检测功能.就是每隔一段时间客户端向服务器端发送一个消息,以检测连接是否正常,发送的消息内容为: <presence id="h09Ke-13&qu ...

  9. golang中的reflect包用法

    最近在写一个自动生成api文档的功能,用到了reflect包来给结构体赋值,给空数组新增一个元素,这样只要定义一个input结构体和一个output的结构体,并填写一些相关tag信息,就能使用程序来生 ...

随机推荐

  1. 规范化的软件项目演进管理--从 Github 使用说起

    规范化的软件项目演进管理 从 Github 使用说起 1   前言 首先,本文的层次定位是:很基本很基础的 Github 工具的入门级应用,写给入门级的用户看的. 基本上工作过几年的人,下面描述的这些 ...

  2. Homework 1 -- The beginning

    我是在北京在读的一位大学生.如果问我学的什么专业,我会用一个冷笑话回答你:我精通多种语言,在老家我说家乡话:跟北京我讲普通话:跟老外就玩English:我跟机器得敲代码.现在你知道我学的就是计算机了. ...

  3. 【读书笔记】Html5游戏开发

    一直对HMTL5做游戏饶有兴趣,而这本书刚好就是HTML5 2游戏初级入门的书.Demo简单注释详细,可以拿来练练手,一个星期左右就可以读完.若要追求酷炫高大上效果,这本书恐怕要让你失望了.但作为上手 ...

  4. KindEditor编辑器For DotNet控件

    KindEditor很不错,刚接触不久,非常喜欢.KindEditor网站有ForPHP等扩展的,没有ForNet的. 我是搞.net开发的,就用它简单封装了一个控件,拖过来即可使用,使用更加简单.源 ...

  5. MySQL模糊查询(like)时区分大小写

    问题说明:通过上面的语句,你会发现MySQL的like查询是不区分大小写的,因为我的失误,把Joe写成了joe才发现了这个东东吧.但是,有时候,我们需要区分大小写的是,该怎么办呢?解决方法如下: 方法 ...

  6. Effective c#学习笔记(1)

    条款1 使用属性代替可访问的数据成员 属性是个啥,谁在用? 1. C#的属性在被访问的时候看起来好像是数据成员,但其实是方法.     2. 在.NET框架中,一般使用属性表达公有数据成员.      ...

  7. SVN修改已提交版本的注释

    SVN提交文件后,发现注释写的不完整或不够明确,想再修改注释文字.通过View Project History dialog修改完成后,在提交时遇到如下错误:Repository has not be ...

  8. Java面向对象思想解决猜拳问题

    第一个面向对象的程序: 一个控制台猜拳小游戏: 第一步选择角色: 第二部选择剪刀,石头,布,与电脑进行PK: 第三部选择继续或者选择结束; 结束显示比赛的局数,以及各自赢得的分数: 设计思路 分析问题 ...

  9. 我心中的核心组件(可插拔的AOP)~分布式文件上传组件~基于FastDFS

    回到目录 一些概念 在大叔框架里总觉得缺点什么,在最近的项目开发中,终于知道缺什么了,分布式文件存储组件,就是缺它,呵呵,对于分布式文件存储来说,业界比较公认的是FastDFS组件,它自己本身就是集群 ...

  10. Atitit 修改密码的功能流程设计 attilax总结

    Atitit 修改密码的功能流程设计 attilax总结 1.1. 注意点1 1.2. 设计修改用户密码功能时把用户ID保存在哪里?1 1.3. Ui设计1 1.4. 功能设计源码1 1.5. Agt ...