信号量 - 初始计数有什么用?

San*_*box 72 c# concurrency multithreading semaphore

http://msdn.microsoft.com/en-us/library/system.threading.semaphoreslim.aspx

要创建信号量,我需要提供初始计数和最大计数.MSDN声明初始计数是 -

可以同时授予的信号量的初始请求数.

虽然它声明最大数量是

可以同时授予的信号量的最大请求数.

我可以理解,最大计数是可以同时访问资源的最大线程数.但是,初始计数的用途是什么?

如果我创建一个初始计数为0且最大计数为2的信号量,则我的线程池线程都不能访问该资源.如果我将初始计数设置为1并将最大计数设置为2,则只有线程池线程可以访问该资源.只有当我将初始计数和最大计数都设置为2时,2个线程才能同时访问资源.那么,我真的很困惑初始计数的意义?

SemaphoreSlim semaphoreSlim = new SemaphoreSlim(0, 2); //all threadpool threads wait
SemaphoreSlim semaphoreSlim = new SemaphoreSlim(1, 2);//only one thread has access to the resource at a time
SemaphoreSlim semaphoreSlim = new SemaphoreSlim(2, 2);//two threadpool threads can access the resource concurrently
Run Code Online (Sandbox Code Playgroud)

SVG*_*reg 64

是的,当初始数字设置为0时 - 所有线程将在您增加"CurrentCount"属性时等待.您可以使用Release()或Release(Int32)来完成此操作.

释放(...) - 将增加信号量计数器

等待(...) - 将减少它

您不能递增计数器("CurrentCount"属性)大于您在初始化中设置的最大计数.

例如:

SemaphoreSlim^ s = gcnew SemaphoreSlim(0,2); //s->CurrentCount = 0
s->Release(2); //s->CurrentCount = 2
...

s->Wait(); //Ok. s->CurrentCount = 1
...

s->Wait(); //Ok. s->CurrentCount = 0
...

s->Wait(); //Will be blocked until any of the threads calls Release()
Run Code Online (Sandbox Code Playgroud)

  • 大声笑,这可能是我第5次达到同样的答案,因为构造函数的文档总是让我对设置的值感到困惑.干杯 (5认同)

Bri*_*eon 55

那么,我真的很困惑初始计数的意义?

这里可能Wait有用的一个重点是减少信号量计数并Release递增它.

initialCount是立即允许的资源访问次数.或者,换句话说,它是Wait在信号量被实例化之后立即调用而不会阻塞的次数.

maximumCount是信号量可以获得的最高计数.Release假设initialCount计数为零,则可以在不抛出异常的情况下调用次数.If initialCount设置为相同的值,maximumCount然后Release在实例化信号量后立即调用将引发异常.

  • 这非常有用!我一直在考虑向后信号量,因为initialCount是初始BLOCKED资源的数量,而不是立即可用的资源数量.谢谢. (11认同)
  • @PhilipTenn,我同意 - 文件在这方面不明确 (2认同)

The*_*ias 10

通常,当SemaphoreSlim用作节流阀时,initialCountmaxCount具有相同的值:

var semaphore = new SemaphoreSlim(maximumConcurrency, maximumConcurrency);
Run Code Online (Sandbox Code Playgroud)

...并且semaphore与此模式一起使用:

await semaphore.WaitAsync(); // or semaphore.Wait();
try
{
    // Invoke the operation that must be throttled
}
finally
{
    semaphore.Release();
}
Run Code Online (Sandbox Code Playgroud)

配置initialCount最大并发策略,并maxCount确保不会违反该策略。如果省略第二个参数( )maxCount,只要代码中没有错误,您的代码也将正常工作。如果存在错误,并且每个错误WaitAsync后面可能有多个Release,那么将maxCount有助于在该错误最终出现在程序的发布版本中之前检测到该错误。该错误将作为 出现SemaphoreFullException,希望在预发布版本的测试期间,这样您就能够在它造成任何真正危害之前(在它导致违反最大并发策略之前)跟踪并消除它。生产环境)。

maxCount如果省略参数,则默认值是Int32.MaxValue源代码)。


Kar*_*tan 7

您希望一次能够访问资源多少个线程?将初始计数设置为该数字.如果该数字在程序的整个生命周期中永远不会增加,请将最大计数设置为该数字.这样,如果您在释放资源方面遇到编程错误,您的程序将崩溃并通知您.

(有两个构造函数:一个只接受初始值,另一个接受最大计数.使用适当的.)


Ern*_*rno 2

这样,当当前线程创建信号量时,它可以从一开始就声明一些资源。