如果是这样,是否可以使其失败(在某种设置中)并且不更改测试代码本身?
func Test_WaitGroup_Simple(t *testing.T) {
var condition bool
var wg sync.WaitGroup
wg.Add(1)
go func() {
condition = true
wg.Done()
}()
wg.Wait()
if !condition {
t.Error("Condition is false. But expected was true.")
}
}
答案 0 :(得分:0)
我已经改变了你的测试,以便在原子模块之间进行比较:
package main
import (
"sync"
// "sync/atomic"
"fmt"
)
func main() {
var condition int32
var wg sync.WaitGroup
wg.Add(1)
go func() {
condition = 101
//atomic.StoreInt32(&condition,101)
wg.Done()
}()
wg.Wait()
if condition != 101 {
fmt.Println("Condition is false. But expected was true.")
} else {
fmt.Println("Ok.")
}
}
https://play.golang.org/p/8ewy2uMNNH
使用go asm,我们可以检查将生成哪些代码
go tool compile -S t.go
这是从
生成内联代码atomic.StoreInt32(安培;条件,101)
0x001d 00029 (t.go:15) MOVL $101, AX
0x0022 00034 (t.go:15) MOVQ "".&condition+24(FP), CX
0x0027 00039 (t.go:15) XCHGL AX, (CX)
0x0029 00041 (t.go:16) MOVQ "".&wg+32(FP), AX
0x002e 00046 (t.go:16) MOVQ AX, (SP)
0x0032 00050 (t.go:16) PCDATA $0, $1
0x0032 00050 (t.go:16) CALL sync.(*WaitGroup).Done(SB)
这是
的制作条件= 101
0x001d 00029 (t.go:14) MOVQ "".&condition+24(FP), AX
0x0022 00034 (t.go:14) MOVL $101, (AX)
0x0028 00040 (t.go:16) MOVQ "".&wg+32(FP), AX
0x002d 00045 (t.go:16) MOVQ AX, (SP)
0x0031 00049 (t.go:16) PCDATA $0, $1
0x0031 00049 (t.go:16) CALL sync.(*WaitGroup).Done(SB)
正如您所看到的,代码没有那么大的区别。我使用int32只是为了清除这两种情况的区别。 但是为其他原子类型生成或多或少相同的代码,包括bool
如果你看一下i386平台上的原子/商店功能的实现,它实际上什么都不做:
同步/原子/ asm_amd64.s
TEXT ·StoreUint32(SB),NOSPLIT,$0-8
MOVL addr+0(FP), BP
MOVL val+4(FP), AX
XCHGL AX, 0(BP)
RET
但是在32平台上存储64位已经很棘手,当然不能用简单的" ="操作
这就是为什么我的答案是:此测试将始终传递至少386和amd64平台。另一件事是不好的做法 - 但实际上是另一张票的故事。
答案 1 :(得分:0)
它不能。见Does WaitGroup.Wait() imply memory barrier in this case?。非常感谢@OlegGolovanov查看了AS的ASM。