我有一段代码应该由小于 N 的最大线程数执行,并且线程调用 someFunction() 的顺序应该反映在它们进入该部分的顺序中,即 FIFO 顺序。
如果我使用信号量,我无法控制线程进入该部分的顺序。
“没有保证的顺序,例如 FIFO 或 LIFO,阻塞的线程进入信号量。”
最初的尝试:
class someClass
{
static volatile Semaphore semaphore;
...
someClass()
{
semaphore = new Semaphore(N,N)
}
someType someFunction(InputType input)
{
try
{
semaphore.WaitOne();
/* Section Begins */
var response = someHeavyJob(input); // submitted to the server
return response;
/* Section Ends */
}
finally
{
semaphore.Release();
}
}
}
如果我将 Semaphore 和 ConcurrentQueue 组合如下,线程可能会返回对其他线程带来的请求的响应,这将需要对代码的其他部分进行重大更改。以下问题的 .NET 4.5 解决方案是什么:
- 允许代码部分中的最大线程数小于 N
- 线程进入section的顺序是FIFO
线程会得到他们带来的请求的响应(而不是其他线程带来的请求的响应)
class someClass { static volatile ConcurrentQueue<someType> cqueue; static volatile Semaphore semaphore; ... someClass() { cqueue = new ConcurrentQueue<someType>(); semaphore = new Semaphore(N,N) } someType someFunction(Request request) { try { cqueue.enqueue(request); semaphore.WaitOne(); Request newrequest; cqueue.TryDequeue(out newrequest); /* Section Begins */ var response = someHeavyJob(Request newrequest); // submitted to the server return response; /* Section Ends */ } finally { semaphore.Release(); } } }
更新:我正在澄清我的问题:SomeHeavyJobs() 函数是对正在处理此作业的服务器的阻塞调用。
UPDATE2:谢谢大家的回答。为了记录:我最终使用了FIFO Semaphore