问题标签 [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 投票
2 回答
1777 浏览

multithreading - 休眠、多线程和竞争条件

使用 NHibernate 异步保存到数据库时,我遇到了竞争条件问题。首先,对数据库的插入是异步完成的,其中唯一的 id 是自动生成的。在此插入返回主线程之前,现在持久对象具有唯一的数据库生成的 id,该对象以某种方式更新。如果我调用 session.Update 更新将失败,因为要更新的对象还没有 id 值。如果我调用 SaveOrUpdate 它显然会导致插入而不是更新,因为我的实体的 id 字段等于未保存的值属性。希望这段代码能让情况更清楚:

一种解决方案是在保存之前在代码中生成唯一 ID。在这种情况下,应用程序管理唯一 id 的递增,而不是数据库。还有其他处理方法吗?

0 投票
1 回答
93 浏览

scala - 有人可以解释这篇关于在 Scala 中执行竞赛安全的文章吗

http://www.infoq.com/news/2009/07/scala-actors-race-safe-system

0 投票
2 回答
1000 浏览

c++ - 虚函数和 pthread_create 之间的竞争

当我尝试使用虚拟方法创建类实例并将其传递给 pthread_create 时,我得到一个竞争条件,导致调用者有时调用基方法而不是像它应该的那样调用派生方法。谷歌搜索后pthread vtable race,我发现这是相当知名的行为。我的问题是,什么是绕过它的好方法?

下面的代码在任何优化设置下都表现出这种行为。请注意,MyThread 对象在传递给 pthread_create 之前是完全构造的。

0 投票
3 回答
704 浏览

flash - AS3 中的竞争条件触发事件

我在以正确的编年史顺序触发和删除事件时遇到了一些麻烦。下面的代码给出了以下输出:

  • 将海报保存到数据库中,并发送事件
  • 调用服务,调度事件已移除 = false
  • 调用服务,调度事件已移除 = false
  • 调用服务,调度事件已移除 = true
  • 将海报保存到数据库中,并发送事件
  • 将海报保存到数据库中,并发送事件

当然这应该更像是:

  • 将海报保存到数据库中,并发送事件
  • 调用服务,调度事件已移除 = true
  • 将海报保存到数据库中,并发送事件
  • 调用服务,调度事件已移除 = true
  • 将海报保存到数据库中,并发送事件
  • 调用服务,调度事件已移除 = true

有人可以帮我弄这个吗?我已经没有关于如何解决这个问题的想法了。

谢谢!

0 投票
2 回答
723 浏览

javascript - Javascript线程竞争条件

编辑:我想出了我在这里发布的原始 YUI3 问题的答案,但它导致了另一个问题,而不是开始一个新线程,我想我只是在这里添加它。请向下滚动查看新问题(以粗体显示)。

原始问题:我在 YUI 定义中创建 JavaScript 倒数计时器时遇到了一些问题,我的猜测与对象范围有关。这是我的代码:

我得到的错误是它没有像我要求它调用那样等待 1000 毫秒timer_trigger(),Safari 最终会问我是否要停止运行代码。当我在加载页面几秒钟后,计时器已经下降到大约 3、4 分钟。我也尝试过使用setTimeout,但这也会产生相同的结果。任何人都可以帮忙吗?我真的很感激!

编辑:我实际上想出了一个解决方案——这是经过数小时尝试大量事情之后的结果,但更多的谷歌搜索有时仍然会产生新的结果/答案(实际上我在这个网站上找到了答案)。

所以显然我的代码正在创建一个竞争条件,我所要做的就是修复它:

我查看了比赛条件,但我不清楚这对我来说意味着什么,以及对我的代码进行看似微不足道的更改如何解决了我遇到的问题。所以回答了原来的问题,但我想把它变成答案产生的问题。

JavaScript 中的线程是如何工作的,是什么导致了我的竞态条件,以及为什么代码中的微小更改修复了我遇到的错误?

0 投票
2 回答
1261 浏览

ruby-on-rails - 如何避免 Ruby on Rails 应用程序中的竞争条件?

我正在开发一个 Rails 应用程序,其中每个子域都有一个单独的数据库。我正在做这样的事情。

现在,在production模式下,请求按此顺序来执行。

  1. 请求“A”针对子域a.example.netMyModel与数据库“a”建立连接。
  2. 现在另一个请求“B”针对子域b.example.netMyModel与数据库“b”建立连接。
  3. 现在,如果请求“A”尝试执行MyModel.find_*()它将访问哪个数据库?“a”还是“b”?

我相信这就是我们所说的“线程安全”或“竞争条件”,如果是这样,那么在每个子域使用一个数据库实现应用程序时,我们如何避免它呢?

在上述问题中,我的假设是同时执行两个请求是生产服务器的正常行为。或者有没有更好的方法。我对生产服务器没有太多经验,所以请指教。

0 投票
1 回答
182 浏览

python - Python 服务文件缓存 Apache 竞争条件

我正在编写一个 python 服务(pyamf),用户可以通过它访问图像。所有图像都存储在中央服务器上。python 服务将在可以通过网络访问服务器的卫星计算机上运行。该服务应按以下方式工作:

  1. 在本地检查文件是否存在,如果存在,使用它。
  2. 在本地检查以查看当前是否正在从服务器传输文件( file.part 存在并且大小正在更改)。如果是这样,请等待下载完成,然后使用 file.
  3. 如果文件不存在且文件未下载,请通过 urlretrieve 下载文件。

问题在于 Apache 的多线程。线程同时到达文件存在检查,因此他们都认为需要下载文件。不用说,这不好。

处理这种竞争条件的正确方法是什么?

谢谢!

0 投票
1 回答
4059 浏览

ruby-on-rails - 在 RSpec 单元测试中模拟竞争条件

我们有一个异步任务,它为对象执行可能长时间运行的计算。然后将结果缓存在对象上。为了防止多个任务重复相同的工作,我们通过原子 SQL 更新添加了锁定:

锁定仅适用于异步任务。对象本身仍可能由用户更新。如果发生这种情况,旧版本对象的任何未完成任务都应丢弃其结果,因为它们可能已过时。使用原子 SQL 更新也很容易做到这一点:

如果对象已更新,则其版本将不匹配,因此将丢弃结果。

这两个原子更新应该处理任何可能的竞争条件。问题是如何在单元测试中验证这一点。

第一个信号量很容易测试,因为它只是设置两个不同的测试,有两种可能的场景:(1)对象被锁定的地方和(2)对象没有被锁定的地方。(我们不需要测试 SQL 查询的原子性,因为这应该是数据库供应商的责任。)

如何测试第二个信号量?在第一个信号量之后但在第二个信号量之前的某个时间,第三方需要更改对象。这将需要暂停执行,以便可以可靠且一致地执行更新,但我知道不支持使用 RSpec 注入断点。有没有办法做到这一点?还是有一些我忽略的其他技术来模拟这种竞争条件?

0 投票
1 回答
410 浏览

mysql - 获取 MYSQL 中的第一个解锁行

当有人访问我的网站时,他会看到浏览量最少的页面。所有页面,包括浏览量计数器,都存储在 MYSQL 数据库中。如果查看页面,则页面浏览计数器会增加一。

如果我的网络服务器有多个线程,我现在会遇到 Racing 情况:

线程 1:用户 A 检索页面 P 的浏览量为 10
线程 2:用户 B 检索页面 P 的浏览量为 10
线程 1:页面 P 的浏览量从 10 增加到 11 并保存
线程 2:页面 P 的浏览量从 10 增加到 11 并保存

所以最后,页面被查看了两次,但 pagecounter 只增加了 1。

一种解决方案是使用 SELECT ... FOR UPDATE 锁定该行,但是,用户 B 必须等到用户 A 正在访问的记录被保存,并且许多线程都试图获取页面浏览量最少的页面,所以会有是一个延迟。

所以我的问题是:当多行被锁定时,是否有可能获得未锁定的第一行,因此线程不必相互等待?如何在 MYSQL 中做到这一点?

我更喜欢导致以下结果的解决方案:

线程1:用户A锁定页面P,浏览量为10
线程2:用户B锁定页面Q,浏览量为11(因为页面P被锁定)
线程1:页面P的浏览量从10增加到11并保存
线程2:页面Q的浏览量从11增加到12并保存

0 投票
3 回答
2430 浏览

c++ - Windows 线程:什么时候应该使用 InterlockedExchangeAdd()?

这个函数的命名似乎是一些复杂的事情。什么时候知道这是要走的路,而不是做这样的事情:

准备 CRITICAL_SECTION cs; int *p = malloc(sizeof(int)); // 分配站点 InitializeCriticalSection(&cs); // 第一次写入的提示

线程 #1 { *p = 1; // 先写 }

线程 #2 { EnterCriticalSection(&cs); *p = 2; // 第二次写入 LeaveCriticalSection(&cs); }

我有一个在一个线程中完成的写入:

然后,我有一个在另一个线程中完成的读取(可能同时):

解决这种竞争条件的最佳解决方案是什么?关键部分是要走的路还是使用 InterlockedExchangeAdd() 更有用?