golang中的race检测
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检测的更多相关文章
- Golang中的自动伸缩和自防御设计
Raygun服务由许多活动组件构成,每个组件用于特定的任务.其中一个模块是用Golang编写的,负责对iOS崩溃报告进行处理.简而言之,它接受本机iOS崩溃报告,查找相关的dSYM文件,并生成开发者可 ...
- golang中锁mutex的实现
golang中的锁是通过CAS原子操作实现的,Mutex结构如下: type Mutex struct { state int32 sema uint ...
- golang中的反射reflect详解
先重复一遍反射三定律: 1.反射可以将"接口类型变量"转换为"反射类型对象". 2.反射可以将"反射类型对象"转换为"接口类型变量 ...
- golang 中 sync.Mutex 的实现
mutex 的实现思想 mutex 主要有两个 method: Lock() 和 Unlock() Lock() 可以通过一个 CAS 操作来实现 func (m *Mutex) Lock() { f ...
- iOS中使用 Reachability 检测网络
iOS中使用 Reachability 检测网络 内容提示:下提供离线模式(Evernote).那么你会使用到Reachability来实现网络检测. 写本文的目的 了解Reachability都 ...
- 浅谈JavaScript中的能力检测
引言 我们知道,各个版本的浏览器有着许多不一致性.理想状态下,应该是所有的浏览器都提供一套标准的API接口.但是现实中,各个版本的浏览器存在的怪癖非常多,我们通常都是使用客户端检测来作为补救措施.但是 ...
- 基础知识 - Golang 中的正则表达式
------------------------------------------------------------ Golang中的正则表达式 ------------------------- ...
- AndroidPN中的心跳检测
在AndroidPN客户端里存在着心跳检测功能.就是每隔一段时间客户端向服务器端发送一个消息,以检测连接是否正常,发送的消息内容为: <presence id="h09Ke-13&qu ...
- golang中的reflect包用法
最近在写一个自动生成api文档的功能,用到了reflect包来给结构体赋值,给空数组新增一个元素,这样只要定义一个input结构体和一个output的结构体,并填写一些相关tag信息,就能使用程序来生 ...
随机推荐
- Ubuntu iptables配置
sudo su sudo apt-get install iptables-persistent modprobe ip_tables #启动iptable #删除原有iptables规则 ipt ...
- Quartz.net(调度框架) 使用Mysql作为存储
最近公司的做的项目中涉及到配置任务地址然后按照配置去目标地址提取相关的数据,所以今天上午在Internet上查看有关定时任务(调度任务)的相关信息,筛选半天然后查找到Quartz.net. Quart ...
- MongoDB索引的使用
Table of Contents 1. 基本索引 2. 联合索引 3. 索引类型 4. 索引管理 1 基本索引 在数据库开发中索引是非常重要的,对于检索速度,执行效率有很大的影响.本 文主要描述了M ...
- DownloadManager
在androi中,volley适合小文件的获取和大并发,如果支持大文件的下载可以用Android原生的DownloadManager.DownloadManager默认支持多线程下载.断点续传等. 基 ...
- Java语法糖4:内部类
内部类 最后一个语法糖,讲讲内部类,内部类指的就是在一个类的内部再定义一个类. 内部类之所以也是语法糖,是因为它仅仅是一个编译时的概念,outer.java里面定义了一个内部类inner,一旦编译成功 ...
- Java多线程20:多线程下的其他组件之CountDownLatch、Semaphore、Exchanger
前言 在多线程环境下,JDK给开发者提供了许多的组件供用户使用(主要在java.util.concurrent下),使得用户不需要再去关心在具体场景下要如何写出同时兼顾线程安全性与高效率的代码.之前讲 ...
- drag & resize元素的jQuery实现
有时项目中会遇到需要拖动元素.拖拽调整元素大小的需求.大部分时候都不想自己写一遍,因为已经有很多现成的例子了.例如jqueryui提供的drag和resize.但是仅仅是为了这么小一个功能就引入一个库 ...
- IOS Animation-CABasicAnimation例子(简单动画实现)
这些例子都是CABasicAnimation的一些简单实现的动画,例如移动.透明度.翻转等等.方法里面传入一个CALayer类或者子类就可以了. 下面是用swift实现的,这些方法我们也可以用作公共类 ...
- Java基础之常用类
1.Collections类: (1)此类完全由在 collection 上进行操作或返回 collection 的静态方法组成. (2)静态方法摘要: static <T> boolea ...
- js中setTimeout()的使用bug
今天用setTimeout()时,遇到一个奇怪的现象,通过多方面的查询,最终解决了问题,这是setTimeout()设计的时候存在的一点点bug. 代码的作用主要是在三秒后自动关闭本浏览器窗口: 代码 ...