棘手的 InterlockedDecrement 与 CriticalSection
有全局长计数
计数器。
线程 A 执行
EnterCriticalSection(&crit);
// .... do something
count++; // (*1)
// .. do something else
LeaveCriticalSection(&crit);
线程 B 执行操作
InterlockedDecrement(&count); // (*2) not under critical secion.
在 (*1) 处,我处于临界区。在(*2),我不是。
如果没有 InterlockedIncrement() ,(*1) 安全吗? (它是受保护的关键部分)。
我需要在 (*1) 处使用 InterlockedIncrement()
吗?
我觉得我可以支持也可以反对。
There is global long count
counter.
Thread A does
EnterCriticalSection(&crit);
// .... do something
count++; // (*1)
// .. do something else
LeaveCriticalSection(&crit);
Thread B does
InterlockedDecrement(&count); // (*2) not under critical secion.
At (*1), I am under a critical section. At (*2), I am not.
Is (*1) safe without InterlockedIncrement()
? (it is protected critical section).
Do I need InterlockedIncrement()
at (*1) ?
I feel that I can argue both for and against.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(3)
您应该使用其中一种,而不是混合使用它们。
虽然 InterlockedDecrement 保证是原子的,但operator++ 却不是,尽管在这种情况下它可能取决于您的体系结构。在这种情况下,您实际上根本没有保护
count
变量。鉴于您似乎想要执行简单的递增/递减操作,我建议您在这种情况下只需删除关键部分并使用关联的 Interlocked* 函数。
You should use one or the other, not mix them.
While
InterlockedDecrement
is guaranteed to be atomic,operator++
is not, though in this case it likely will be depending upon your architecture. In this case, you're not actually protecting thecount
variable at all.Given that you appear to want to do simple inrecrement/decrement operations, I would suggest that you simply remove the critical section in this case and use the associated
Interlocked*
functions.两个线程都应使用任一
InterlockedDecrement
/InterlockedIncrement
、或同一临界区。混合和匹配没有理由正常工作。考虑以下事件序列:
最终结果:你丢失了一个减量!
关键部分的一个有用的(如果故意简化的话)心智模型是这样的:进入关键部分所做的就是阻止其他线程进入同一个临界区。它不会自动阻止其他线程执行可能需要同步的其他操作。
InterlockedDecrement 所做的一切就是确保递减的原子性。它不会阻止任何其他线程对变量的过时副本执行计算,然后将结果写回。
Both threads should use either
InterlockedDecrement
/InterlockedIncrement
, or the same critical section. There is no reason for the mixing and matching to work correctly.Consider the following sequence of events:
Net result: you've lost a decrement!
A useful (if deliberately simplified) mental model for critical sections is this: all entering a critical section does is prevent other threads from entering the same critical section. It doesn't automatically prevent other threads from doing other things that may require synchronization.
And all
InterlockedDecrement
does is ensure the atomicity of the decrement. It doesn't prevent any other thread performing computations on an outdated copy of the variable, and then writing the result back.是的,你知道。
否则可能是:
读取值
该值以原子方式递增
原始值递增并写入,使之前的原子更新失效
。此外,两者都需要相同的关键部分,因为它无助于锁定单独的事物。 :)
Yes, you do.
Otherwise it could be that:
The value is read
The value is incremented atomically
The original value is incremented and written, invalidating the previous atomic update
Furthermore, you need the same critical section for both, since it doesn't help to lock on separate things. :)