【发布时间】:2021-09-07 08:58:23
【问题描述】:
遇到以下代码,当同时调用 GenerateLabel 超过 4 次时,这些代码会阻塞信号量。在 WaitOne 之后,成员 mCurrentScanner 用于访问扫描仪。问题是 WaitOne 之后是否需要 Interlocked 功能?我会说不,因为当 WaitHandle 被释放时线程会重新开始,但不是 100% 确定。
mConcurrentLabels = new Semaphore(4, 4);
public string GenerateLabel()
{
mConcurrentLabels.WaitOne();
int current = 0;
Interlocked.Exchange(ref current, mCurrentScanner);
(scanner, dir) = ScanMappings[current];
Interlocked.Increment(ref mCurrentScanner);
mCurrentScanner %= 4;
DoLongRunningTask();
mConcurrentLabels.Release();
}
【问题讨论】:
-
即使使用联锁方法,这似乎仍然存在问题,因为您所做的一切都是访问数组和修改/旋转 int,我建议您只使用锁并完成它跨度>
-
DoLongRunningTask 大约需要 10-20 秒,同时其他呼叫可能会进来,因此更多的是保护 DoLongRunningTask 所做的事情。但不确定是否绝对需要 Interlocked 来保护两个调用以获得相同的索引