程序有并发错误?NO WAY!

什么是并发错误

并发是指程序能够交替执行不同的任务,以达到"同时执行效果",加快程序的运行效率。

但是并发也会导致一系列问题,以变量+1赋值为例,由于操作实际由多条指令组成,不同任务执行指令的顺序可能是交错的,所以就可能出现执行结果与我们预期结果不符合的情况。

并发错误很难捕获。这是因为触发并发错误需要线程以特定的顺序并行执行指令,以使程序显示错误行为。此外,触发并发错误具有不确定性。即使在触发并发错误之后,由于非确定性,将其重现并调试也可能很困难。

如果您是.NET开发者,可以尝试使用Coyote来自动检测并发错误。

Coyote

Coyote是由微软研究院提供的一个.NET库,旨在帮助确保您的代码没有并发错误。

Coyote的核心是一个调度器,它在测试期间控制(通过二进制重写)程序的执行,并且能够系统地研究并发性和不确定性,以发现安全性和活跃性缺陷。

更为重要的是,一旦Coyote发现一个错误,一旦 Coyote 发现了一个错误,它就可以让您根据需要多次完全重现它,从而使调试和修复问题变得更加容易。

你可以运行下面的命令安装Coyote:

dotnet tool install --global Microsoft.Coyote.CLI

下面我们用官方示例程序https://github.com/microsoft/coyote-samples来体验一下Coyote的强大功能。

定位错误

首先,clone下代码后,运行下列命令进行编译示例程序代码:

powershell -f build.ps1

运行下列命令进行错误检查:

cd bin\net5.0\

coyote rewrite BoundedBuffer.dll

coyote test BoundedBuffer.dll -m TestBoundedBufferMinimalDeadlock --iterations 100

测试完成后,将会提示发现错误,如下图: 

您将得到一个解释所有这些的日志文件:

<ErrorLog> Deadlock detected. Task(0) is waiting for a task to complete, 
but no other controlled tasks are enabled. 
Task(1), Task(2) and Task(3) are waiting to acquire a resource that is already acquired, 
but no other controlled tasks are enabled.
<StackTrace>    at Microsoft.Coyote.Tasks.SynchronizedBlock.Mock.Wait()
   at BoundedBufferExample.BoundedBuffer.Take()

解决问题

通过错误日志的StackTrace,定位到出错代码:

while (this.Occupied == 0)
{
    Monitor.Wait(this.SyncObject);
}

然后看看释放SyncObject的代码:

 Monitor.Pulse(this.SyncObject);

根据错误日志的ErrorLog,并对照官方文档的解释,只需要把Pulse替换成PulseAll即可解决问题:


结论

通过上面的示例,我们可以看到,未对代码做任何修改,就可以实现并发错误检测。

如果您对项目中的多线程代码不太放心,可以尝试使用Coyote来帮助检测,避免上线出现并发错误的可能性。

如果你觉得这篇文章对你有所启发,请关注我的个人公众号”My IO“,记住我!

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值