问题标签 [interlocked-increment]

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 投票
6 回答
11452 浏览

c# - C# 多线程无符号增量

我想从多个线程中增加一个无符号整数。

我知道 Interlocked.Increment,但它不处理无符号整数。我可以使用 lock(),但出于性能原因,我宁愿不使用。

仅以正常方式递增它是线程安全的吗?偶尔的增量是否丢失也没关系,因为它仅用于统计。我不想要的是被破坏的价值。

0 投票
5 回答
531 浏览

c++ - 我可以使用联锁操作来更新多个值以避免锁定关键部分/互斥锁吗?

我有一个多线程应用程序 (C++),我需要在其中增加/更改一系列值。如果我使用一系列互锁操作,它们是否被视为单个原子操作?就像在这个例子中一样:

还是给我们一个锁来执行同步会更好?像这样:

我认为需要锁,但我不确定......所有值都处于旧状态或新状态非常重要。

0 投票
6 回答
16382 浏览

.net - Interlocked.Increment 的性能

在各种平台上Interlocked.Increment(ref x)比整数和长整数更快还是更慢?x++

0 投票
3 回答
2591 浏览

multiprocessing - InterlockedIncrement 与 ++

InterlockedIncrement 是如何工作的?

是否只关注多处理器系统?

它有什么作用,禁用所有处理器的中断?

0 投票
3 回答
1378 浏览

c# - C# 阻塞 FIFO 队列会泄漏消息吗?

我正在做一个学术开源项目,现在我需要在 C# 中创建一个快速阻塞 FIFO 队列。我的第一个实现只是将一个同步队列(带动态扩展)包装在读取器的信号量中,然后我决定以以下(理论上更快)的方式重新实现

这是我们在教科书中找到的带有静态数组的经典 FIFO 队列实现。它旨在以原子方式递增指针,并且由于我无法使指针在达到(容量-1)时回到零,因此我计算模数。从理论上讲,使用 Interlocked 与在进行增量之前锁定相同,并且由于存在信号量,因此可以有多个生产者/消费者进入队列,但一次只能修改一个队列指针。首先,因为 Interlocked.Increment 先递增,然后返回,我已经明白我仅限于使用后递增值并从数组中的位置 1 开始存储项目。没问题,到了一定值我就回0了

它有什么问题?您不会相信,在重负载下运行时,有时队列会返回 NULL 值。我确定,重复一遍,我确定,没有任何方法将null排入队列。这绝对是正确的,因为我尝试在 Enqueue 中进行空检查以确保没有抛出任何错误。我用 Visual Studio 为此创建了一个测试用例(顺便说一下,我使用像 maaaaaaaany 人这样的双核 CPU)

一旦消费者线程得到一个空值,就会计算一个错误。当使用 1 个生产者和 1 个消费者执行测试时,它成功了。当使用 2 个生产者和 2 个消费者或更多进行测试时,会发生灾难:甚至检测到 2000 次泄漏。我发现问题可能出在 Enqueue 方法中。根据设计合同,生产者只能写入空的单元格(null),但是通过一些诊断修改我的代码我发现有时生产者试图在非空单元格上写入,然后被“好“ 数据。

然后经常发生“太糟糕”的异常。但是并发写入引发的冲突太奇怪了,因为增量是原子的,并且写入器的信号量只允许与空闲数组单元一样多的写入器。

有人可以帮我吗?如果您与我分享您的技能和经验,我将不胜感激。

谢谢你。

0 投票
3 回答
488 浏览

c# - 第一个进入的线程如何向其他并发线程发出相同方法结束的信号?

第一个进入的线程如何向其他并发线程发出相同方法结束的信号?

我有一个名为 PollDPRAM() 的方法。它必须通过网络访问一些慢速硬件并刷新对象私有数据。如果相同的方法被其他线程同时调用,它们一定不能执行此行程,而是等待第一个到来的线程完成工作并简单地退出,因为数据是新鲜的(比如 10-30 毫秒前没有区别) . 在不先进入第二、第三等线程的方法中很容易检测到。我使用联锁计数器来检测并发性。

问题:我通过观察计数器 (Interlocked.Read) 来检测第一个线程的退出是一个糟糕的选择,以便在计数器减少到小于在 n>1 线程入口处检测到的值之后进行观察。选择很糟糕,因为第一个线程在离开后几乎可以立即重新进入该方法。所以 n>1 线程永远不会检测到计数器的下降。

所以问题:如何正确检测第一个进入的线程已经退出方法,即使这个第一个线程可以立即再次进入它?

谢谢

PS 一段代码

0 投票
2 回答
1285 浏览

.net - 如果 Interlocked.Increment 是原子的,为什么我应该使用 ++ 代替?

我认为这个原子操作比++. 我只看到有利的一面Interlocked.Increment。它的缺点是什么?

0 投票
3 回答
3461 浏览

c++ - 互锁变量访问和临界区互锁增量之间的区别

有人可以帮助解释c ++中互锁变量访问和关键部分互锁增量之间的区别吗?谢谢,非常感谢,提前。

0 投票
1 回答
346 浏览

multithreading - 使用“不安全”线程函数是否安全?

请原谅我略带幽默的标题。我在其中使用了“安全”一词的两种不同定义(显然)。

我对线程相当陌生(好吧,我已经使用线程很多年了,但只是非常简单的形式)。现在我面临着编写一些算法的并行实现的挑战,并且线程需要处理相同的数据。考虑以下新手错误:

初学者可能希望上面的代码显示消息20000000。确实,首先value等于0,然后我们inc乘以20000000。但是,由于该inc过程不是“原子的”,因此两个线程会发生冲突(我猜这inc会做三件事:读取、递增和保存),因此很多incs 将被有效地“丢失”。我从上面的代码中得到的一个典型值是10030423.

最简单的解决方法是使用InterlockedIncrement代替Inc(在这个愚蠢的例子中会慢得多,但这不是重点)。另一种解决方法是将inc关键部分放在内部(是的,在这个愚蠢的例子中也会很慢)。

现在,在大多数实际算法中,冲突并不常见。事实上,它们可能非常罕见。我的一种算法创建了DLA 分形,而我不时产生的变量之一inc是吸附粒子的数量。这里的冲突非常罕见,更重要的是,我真的不在乎变量的总和是否为 20000000、20000008、20000319 或 19999496。因此,很容易使用InterlockedIncrement或临界区,因为它们只会使代码膨胀并使其(稍微)慢到没有(据我所见)好处。

但是,我的问题是:冲突的后果是否比递增变量的稍微“不正确”的值更严重?例如,程序会崩溃吗?

诚然,这个问题可能看起来很愚蠢,因为毕竟使用InterlockedIncrement而不是的成本inc相当低(在许多情况下,但不是全部!),因此(也许)不安全是愚蠢。但我也觉得在理论上知道它是如何工作的会很好,所以我仍然认为这个问题很有趣。

0 投票
3 回答
3121 浏览

c# - 对 Interlocked.Increment 和 Lock 的使用感到困惑

我了解 和 的Interlocked.Increment功能lock()。但我对何时使用其中一种感到困惑。据我所知,Interlocked.Increment增量共享 int/long 值,而 aslock()旨在锁定代码区域。

例如,如果我想更新字符串值,可以使用lock()

但是,这在课堂上是不可能的Interlocked

  • 为什么这不能通过 来完成Interlocked
  • 这些同步机制有什么区别?