gpt4 book ai didi

testing - golang中如何测试并发和锁?

转载 作者:IT王子 更新时间:2023-10-29 00:37:06 25 4
gpt4 key购买 nike

我们正在尝试测试锁。基本上,有多个客户端试图获得对特定 key 的锁定。在下面的示例中,我们使用了键“x”。

我不知道如何测试锁定是否有效。我只能阅读日志以确定它是否正常工作。

正确的事件顺序应该是:

  1. client1 获得 key “x”的锁
  2. client2 尝试获取键“x”上的锁 (fmt.Println("2 getting lock")) - 但被阻止并等待
  3. client1 释放对键“x”的锁定
  4. client2 获得 key “x”的锁

问题 1:如何使流程自动化并将其转化为测试?

问题 2:测试并发/互斥锁定的一般技巧有哪些?

func TestLockUnlock(t *testing.T) {
client1, err := NewClient()
if err != nil {
t.Error("Unexpected new client error: ", err)
}

fmt.Println("1 getting lock")
id1, err := client1.Lock("x", 10*time.Second)
if err != nil {
t.Error("Unexpected lock error: ", err)
}
fmt.Println("1 got lock")

go func() {
client2, err := NewClient()
if err != nil {
t.Error("Unexpected new client error: ", err)
}
fmt.Println("2 getting lock")
id2, err := client2.Lock("x", 10*time.Second)
if err != nil {
t.Error("Unexpected lock error: ", err)
}
fmt.Println("2 got lock")

fmt.Println("2 releasing lock")
err = client2.Unlock("x", id2)
if err != nil {
t.Error("Unexpected Unlock error: ", err)
}
fmt.Println("2 released lock")
err = client2.Close()
if err != nil {
t.Error("Unexpected connection close error: ", err)
}
}()

fmt.Println("sleeping")
time.Sleep(2 * time.Second)
fmt.Println("finished sleeping")

fmt.Println("1 releasing lock")
err = client1.Unlock("x", id1)
if err != nil {
t.Error("Unexpected Unlock error: ", err)
}

fmt.Println("1 released lock")

err = client1.Close()
if err != nil {
t.Error("Unexpected connection close error: ", err)
}

time.Sleep(5 * time.Second)
}

func NewClient() *Client {
....
}

func (c *Client) Lock(lockKey string, timeout time.Duration) (lockId int64, err error){
....
}

func (c *Client) Unlock(lockKey string) err error {
....
}

最佳答案

基于锁的代码的并发测试很难,以至于很难找到可证明正确的解决方案。通过打印语句进行临时手动测试并不理想。

有四个本质上不可测试的动态并发问题 (more)。除了性能测试之外,统计方法是您可以通过测试代码实现的最佳方法(例如,确定 90 个百分位数的性能优于 10 毫秒,或者死锁的可能性小于 1%)。

这是 Go 提供的通信顺序进程 (CSP) 方法比共享内存上的锁更好用的原因之一。考虑您的 Goroutine 被测提供了一个具有指定行为的单元。这可以针对其他 Goroutines 进行测试,这些 Goroutines 通过 channel 提供必要的测试输入并通过 channel 监控结果输出。

对于 CSP,使用没有任何共享内存(并且没有任何通过指针无意共享的内存)的 Goroutines 将保证在任何数据访问中都不会出现竞争条件。使用某些经过验证的设计模式(例如 Welch, Justo and WIllcock )可以确定 Goroutine 之间不会出现死锁。然后确定功能行为是否正确,上面提到的 Goroutine 测试工具可以很好地完成这项工作。

关于testing - golang中如何测试并发和锁?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/19189542/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com