繁体   English   中英

这会导致事件驱动的编程中出现竞争状况吗?

[英]Will this lead to a race condition in event-driven programming?

我正在离散仿真器中编写一个基于代理的小型交互仿真,并开始编写一些类似于以下内容的代码。 我以前没有一些事件驱动的编程,但是没有真正观察到这种情况。 我想知道下面的代码段在更新msgRcvd的值时msgRcvd会导致竞争状态。

// Following is the event-loop per-se
Controller {
    if (...) {
       SendMessage(currentTime() + 5, i,j)
       SendMessage(currentTime() + 5, i,k)
    }
    print currentTime(), msgsRcvd
    Schedule(currentTime()+1, Controller)
}

// The following function is called when an 
// agent receives a message
Receive(Agent agent) {
    if (...) {
       msgsRcvd++ // <-- this is a global variable
    }
}

我的理解是,在currentTime() + 5两种药物在同一时间 ,因为这两个事件在相同的逻辑发生时间收到消息,所以我应该看到的消息数量为2? 还是我会看到发生一些奇怪的竞争情况,并且该值取决于调度程序(即最终可能打印1或2)? 有什么建议么?

答案取决于事件传输的实现,并且在这种意义上与语言无关。

在我使用过的所有系统中,每条消息都将分别放入事件队列中,接收代理将按顺序从该队列中取出事件。 假设您有一个线程生成消息,而有一个事件使消息脱离队列,那么我看不到出现竞争状况的机会。

如果您的事件队列具有某种智能,可以尝试根据时间戳合并事件,那么您只会在接收代理中看到一个事件。 我不知道这样做的通用系统(尽管某些UI系统可能例如将两次快速鼠标单击合并为双击...,但这是特定事件系统的特定行为,而与语言/平台无关)。

否,即使该代理程序代码非常可疑且看起来很危险,我也看不到在这种情况下会产生竞争状况:msgsRcvd应该始终以正确的总数结尾。 即使调度程序恰好在增量之前中断了agent1,在我看来,控制总是会返回来使增量完成。 如果控制器获得控制权,则可能是它将报告MsgsRcvd的不正确内容,但是那又如何呢? MsgsRcvd很快恢复了同相状态。

不过,这肯定是一段令人恐惧的代码。 当我查看这种代码时,我总是想将MsgsRcvd的增量向上移动到控制器中,在该处公开一个将执行增量的函数。 但这只会使我在这种情况下感觉更好; 它不会改变逻辑,也无法解决MsgsRcvd有时会暂时不准确的“问题”(如果是的话)。

本来要提到的是,没有语言/平台不可知的方式来回答这个问题,但是Eric J.涵盖了这一点。

在C ++中,除非平台保证回调将被序列化,否则编写的代码将不安全。 原因是增量运算符不是原子的,并且如果两个线程同时尝试更新该值,则根据获取,添加和存储的顺序可能发生任何事情。

如果该平台的设计真正考虑了并发性,那么应该有一个“互锁/原子” api提供所需的功能。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM