程序有并发错误?NO WAY!

Posted dotNET跨平台

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了程序有并发错误?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“,记住我!

以上是关于程序有并发错误?NO WAY!的主要内容,如果未能解决你的问题,请参考以下文章

TP5报如下的错误 Indirect modification of overloaded element of thinkpaginatorCollection has no effect(代码片段

on the go way 服务器并发

附加到片段的片段对话框不调用 onYes/No 方法

片段不起作用并且有错误

golang goroutine例子[golang并发代码片段]

ubuntu16.04 yum报错:There are no enabled repos. Run “yum repolist all“ to see the repos you have.(代码片段