问题标签 [race-condition]

For questions regarding programming in ECMAScript (JavaScript/JS) and its various dialects/implementations (excluding ActionScript). Note JavaScript is NOT the same as Java! Please include all relevant tags on your question; e.g., [node.js], [jquery], [json], [reactjs], [angular], [ember.js], [vue.js], [typescript], [svelte], etc.

0 投票
3 回答
3355 浏览

windows - PostMessage 偶尔会丢失一条消息

我编写了一个多线程 Windows 应用程序,其中线程:
A – 是一个处理用户交互并处理来自 B 的数据的 Windows 窗体
。B – 偶尔生成数据并将两个 A 传递给它。

线程安全队列用于将数据从线程 B 传递到 A。入队和出队函数使用 Windows 临界区对象进行保护。

如果调用 enqueue 函数时队列为空,该函数将使用 PostMessage 告诉 A 队列中有数据。该函数检查以确保对 PostMessage 的调用成功执行,如果不成功则重复调用 PostMessage(PostMessage 尚未失败)。

这在相当长的一段时间内运行良好,直到一台特定的计算机开始丢失偶尔的消息。丢失的意思是, PostMessage 在 B 中成功返回,但 A 从未收到消息。这会导致软件出现冻结。

我已经想出了几个可接受的解决方法。我很想知道为什么 Windows 会丢失这些消息,以及为什么这只发生在一台计算机上。

这是代码的相关部分。

0 投票
2 回答
1558 浏览

c# - WCF 中使用非单向方法的竞争条件

我正在设计一个客户端-服务器聊天应用程序(实际上我不是,但让我们假装我是:)),我对我所经历的一些竞争条件感到有些困惑。

假设我有以下代码:

这是绑定配置的摘录:

这当然是某种伪 c#,为了清楚起见,我删除了很多不相关的代码。

现在切入正题:此代码不起作用。当我调用 BroadcastMessage 时,该方法永远不会返回,并且我最终在客户端出现超时。如果我在服务器端进行调试,一切似乎都很好(我完全按照预期从 BroadcastMessage 方法返回,并且我不会阻止任何 ReceiveMessage 单向调用)

以下是修复此代码的两种方法:

  1. 删除 FaultContract 并将 BroadcastMessage 方法声明为 oneway=true
  2. 向所有人广播消息,但最初的发件人

我的第一个猜测是客户端正在等待服务器返回,因此无法处理来自服务器的传入 ReceiveMessage 调用,从而阻塞服务器,但 ReceiveMessage 被声明为单向,并且调试服务器表明它不会阻止对 ReceiveMessage 的任何调用

现在,我的问题:

  • 这是怎么回事?

  • 还有其他方法可以解决这个问题吗?(也许通过调整绑定配置?)

  • 假设我选择了修复 2(即不向发送者广播),如果服务器在我等待自己的 BroadcastMessage 调用完成时调用我的 ReceiveMessage 回调(因为其他人向我发送了消息)会发生什么?

  • 我读过 OneWay 调用并不完全是单向的,服务器仍在等待来自另一端的 HTTP 响应。有这方面的详细信息吗?具体来说,当远程呼叫被阻止时,客户端是否能够响应此类 http 响应?

编辑:服务器端的控制台 .net 3.5,客户端的 Winforms .net 3.5

0 投票
7 回答
600 浏览

java - 在多线程(Java 或 .Net)程序中,我可以假设复制变量是原子的吗?

当我想知道这个问题时,我担心我正在设计的应用程序中的竞争条件。

假设我有一个由程序的一个组件管理的大型数组或某种集合,我们称该组件为 Monitor。它的工作是定期检查集合是否“脏”,即最近发生了变化,如果是,则将快照写入磁盘(这是在应用程序发生崩溃时检查点)并再次将其标记为干净。

同一程序的其他组件,在不同的线程中运行,调用监视器的方法来添加数据或修改数组/集合中的数据。这些方法将集合标记为脏。

现在,更改方法在其他组件的线程中运行,对吗?如果我不是那么幸运,可能会在将快照写入磁盘时调用它们,更改已写入的数据,设置脏标志,然后监视器的线程将其取消设置,而无需保存更改(它当它改变时已经超过了元素)。所以我有一个被标记为干净的脏集合。

有一段时间,我想我可以通过制作一个临时的集合副本来解决这个问题,把它标记为干净,然后去序列化这个副本。但是复制会是原子的吗,即我可以确定在我复制时集合不会改变吗?

同时,我想我找到了更好的解决方案,比如

  • 在开始写入磁盘之前设置锁定标志,并使数据更改方法等到取消设置标志
  • 让数据更改方法写入“更改队列”而不是直接写入集合,并让线程执行该队列的磁盘写入过程

我认为锁定标志可能是最好的方法。但我还是很好奇:复制变量是原子的吗?


追问:也许这应该是一个问题,但实际上它非常相似。根据下面的答案,我的“锁定标志”方法也可能不起作用,对吧?因为数据更改方法可能会在锁定标志设置为“锁定”值时检查锁定标志并确定它没有被锁定。因此,如果我真的想正确地做到这一点,我需要一个像互斥锁这样的特殊结构,对吗?


感谢埃里克森对我的后续行动的非常有帮助的回答。我真的应该提出这两个问题,所以我可以接受两个答案。请也给他投票。

0 投票
4 回答
371 浏览

.net - 锁将如何响应竞争条件?

在以下场景中,线程将等待竞争条件多长时间?

将文件添加到集合中:

然后以类似的方式将其从集合中删除。

如果一个线程在服务从集合中删除它时试图添加到集合中,谁会赢?

或者这是比赛条件的关键,你无法预测谁会赢?

0 投票
4 回答
3833 浏览

asp.net - ASP.NET/静态类竞争条件?

我有一个包含大量动态内容的 ASP.NET 应用程序。属于特定客户端的所有用户的内容都是相同的。为了减少每个请求所需的数据库命中次数,我决定缓存客户端级数据。我创建了一个静态类(“ClientCache”)来保存数据。
迄今为止,该类最常用的方法是“GetClientData”,它返回一个 ClientData 对象,其中包含特定客户端的所有存储数据。但是,ClientData 是延迟加载的:如果请求的客户端数据已经缓存,则调用者获取缓存的数据;否则,获取数据,添加到缓存中,然后返回给调用者。

最终,我开始在将 ClientData 对象添加到缓存的行的 GetClientData 方法中出现间歇性崩溃。这是方法体:

异常文本总是类似于“已存在具有相同键的对象”。当然,我尝试编写代码,以便如果客户端已经存在,则无法将其添加到缓存中。

在这一点上,我怀疑我有一个竞争条件并且该方法同时执行了两次,这可以解释代码是如何崩溃的。但是,我感到困惑的是,该方法如何可以同时执行两次。据我所知,任何 ASP.NET 应用程序一次只能处理一个请求(这就是我们可以使用 HttpContext.Current 的原因)。

那么,这个错误是否可能是一个需要在关键部分加锁的竞争条件?还是我错过了一个更明显的错误?

0 投票
1 回答
554 浏览

javascript - IE8——JS的异步验证?

所以我在 ie8 中使用 jquery 和各种 javascript 文件看到了一些奇怪的问题。这些错误不会发生在 Firefox、Safari 或以前版本的 IE 中。发生的主要事情是变量未定义、括号不匹配错误等……但是每次您强制刷新页面时,错误都会发生变化。检查引用的文件没有发现这样的语法错误。

我的问题是,首先,有没有其他人看到过这样的错误?它似乎类似于异步事件的问题。这是否与 IE8 中新的多进程/多线程浏览功能有关?IE 8 是否会在 js 文件下载后立即对其进行某种验证?

提前致谢。

更新:看起来它正在将接收到的 js 文件的元素改组到一个更大的 js 文件中。在调试器中,它显示了来自一个文件的方法,就在另一个文件的代码中间。找不到“导入”段所依赖的代码。不知道这里发生了什么......

0 投票
4 回答
1772 浏览

mysql - MySQL 竞争条件

这是否会导致 MySQL (InnoDB) 的竞争条件:

  1. 开始交易。

  2. 尝试获取记录。

  3. 如果记录不存在,则返回。

  4. 如果记录存在,请将其删除并添加一个日志条目,说明已删除。

  5. 结束事务(提交/回滚)。

是否可以在 2b 中的删除步骤之前启动另一个进程,检测记录的存在,然后让两个进程在日志中输入项目删除条目?

我需要采取什么预防措施吗?

谢谢。

0 投票
2 回答
1437 浏览

iphone - NSURLConnection 上的 Apple SDK 文档中存在错误或混淆?

我最近一直在学习 Apple SDK(用于 iPhone 等)并且遇到了一些我无法理解的东西。在http://developer.apple.com/documentation/Cocoa/Conceptual/URLLoadingSystem/Tasks/UsingNSURLConnection.html的“使用 NSURLConnection”的文档中

我发现了一段奇怪的解释和示例代码。首先,它说:

收到 initWithRequest:delegate: 消息后立即开始下载。它可以在委托接收到 connectionDidFinishLoading: 或 connection:didFailWithError: 消息之前的任何时间通过向连接发送取消消息来取消。

接下来,它显示以下代码:

因此,在我看来,一旦连接初始化,下载必须立即在不同的线程中开始。这很清楚,因为代码是非阻塞的,并将消息发送回委托,在本例中为 self。然而,receivedData 的(自动释放风格)分配发生另一个线程启动之后。这不是不安全的比赛条件吗?如果服务器响应非常快(例如通过环回设备)或线程调度不顺利,这不会导致崩溃、内存泄漏或数据丢失吗?在初始化theConnection之前分配receivedData,然后在上面的else情况下释放它不是更有意义吗?

我被这段代码弄糊涂了,希望有人能为我解释一下。感谢您提供任何信息,

鲁迪·奇里布拉西

0 投票
1 回答
3483 浏览

mysql - MySQL:防止竞争条件 - FOR UPDATE 或 LOCK IN SHARE MODE?

这是我想要的交易顺序:

  1. User1 选择字段,执行操作,用新值更新。
  2. User2 选择字段,执行操作,用新值更新。
  3. User3 选择字段,执行操作,用新值更新。

据我了解,第一个选择仅执行写锁定,而第二个选择执行读写锁定。

两者似乎都可用,但在第一种情况下,User2 会读取什么值?User1 更新前的初始值,还是 User1 更新后的值(这是我想要的)?

所以我很困惑,我应该使用 SELECT ... FOR UPDATE 还是 SELECT ... LOCK IN SHARE MODE?

0 投票
6 回答
8324 浏览

parallel-processing - 糟糕的性能 - 一个简单的开销问题,还是存在程序缺陷?

我在这里有一个我理解的相对简单的 OpenMP 构造。问题在于,与 2 个线程相比,1 个线程的程序运行速度要快 100-300 倍。该计划的 87% 用于gomp_send_wait(),另外 9.5% 用于gomp_send_post.

该程序给出了正确的结果,但我想知道代码中是否存在导致某些资源冲突的缺陷,或者仅仅是线程创建的开销对于块大小为 4 的循环来说完全不值得。 p范围从 17 到 1000,取决于我们模拟的分子的大小。

我的数字是针对最坏情况的,当 p 为 17 且块大小为 4 时。无论我使用静态、动态还是引导式调度,性能都是相同的。使用p=150和块大小75,程序仍然比串行慢 75x-100x。