有人能给我解释一下golang的这种数据竞争行为吗?

有人能给我解释一下golang的这种数据竞争行为吗?,go,Go,如果这是一个已经被问过的问题,我不知道要寻找什么,所以如果是,请提前道歉 我是golang的新手,我在玩goroutines时发现,在编译以下代码时: 主程序包 进口( “fmt” “数学/大” “同步” ) 常数( 工作计数=5 线程数=1 ) 类型workerResult struct{ 作业int64 进程ID int 结果*big.Int } func main(){ var hashMap sync.Map 作业:=制造(chan int64,作业计数) 结果:=制造(chan wor

如果这是一个已经被问过的问题,我不知道要寻找什么,所以如果是,请提前道歉

我是golang的新手,我在玩goroutines时发现,在编译以下代码时:

主程序包
进口(
“fmt”
“数学/大”
“同步”
)
常数(
工作计数=5
线程数=1
)
类型workerResult struct{
作业int64
进程ID int
结果*big.Int
}
func main(){
var hashMap sync.Map
作业:=制造(chan int64,作业计数)
结果:=制造(chan workerResult,作业计数)
var wg sync.WaitGroup
对于i:=0;i
big.Int
的作业文档说明:

整数表示有符号多精度整数。整数的零值表示值0

操作始终采用指针参数(*Int)而不是Int值,每个唯一的Int值都需要自己的唯一*Int指针。要“复制”一个Int值,必须使用Int.set方法将现有(或新分配的)Int设置为一个新值;不支持Int的浅拷贝,这可能会导致错误

因此,我们将在程序中使用
Int.Set
,以消除竞争条件

主程序包
进口(
“fmt”
“数学/大”
“同步”
)
常数(
工作计数=5
线程数=1
)
类型workerResult struct{
作业int64
进程ID int
结果*big.Int
}
func main(){
var hashMap sync.Map
作业:=制造(chan int64,作业计数)
结果:=制造(chan workerResult,作业计数)
var wg sync.WaitGroup
对于i:=0;ijobs第一个程序有一个数据竞争。该方法修改接收器并返回接收器。这与编译器无关。始终使用竞争检测器进行测试。抱歉,我不明白,当我没有在第一个和最后一个之间触摸代码时,第二个程序怎么没有数据竞争?@Myownway code with racing I问题可能会以意想不到的方式出现。请务必使用种族检测器并告诉我们您的发现!我使用-race参数运行它,并将输出放在主线上。另一个例子是种族检测器拯救了这一天。我很喜欢它!我知道您在那里做了什么,但仍然不明白为什么在我对工作进行字符串转换时,种族状况消失了呃,而不是在主函数中,您操作的是一个副本,而不是指向
big.Int
.Calling String()的指针在存储相应的
字符串的位置分配内存。因此,在第一个中,每当我计算新值时,我只是销毁散列结果?正确吗?编辑:实际上,我在两个上都销毁散列结果,但在第二个上,我在字符串被销毁之前分配它是的,多个goroutine corrupted它。假设您正在访问一个元素x。一个goroutine即将读取该值,但另一个goroutine更改了它。因此,在为x写入之前的值丢失了。您还可以考虑其他可能的方法。从种族检测器的输出,可以非常清楚发生了什么。