我正在学习c#信号量,并且不了解一点。我可以像这样初始化Semaphore:
var semaphore = new Semaphore(4, 6);
在很多地方都有这样的解释:
如果你想为调用线程保留一些插槽,你可以这样做 所以通过使第一个参数小于第二个参数。
这是否意味着只有主线程可以使用剩余的2个资源槽?这是否意味着如果我这样写:
var semaphore = new Semaphore(0, 6);
只有主线程可以使用全部6个插槽?
答案 0 :(得分:2)
信号量就像一个夜总会:它具有一定的容量,由保镖强制执行。一旦它满了,没有更多人可以进入,并且队列在外面建立起来。然后,对于每个离开的人,一个人从队列的头部进入。构造函数至少需要两个参数:夜总会当前可用的地点数量和俱乐部的总容量。
答案 1 :(得分:1)
与lock(Monitor)和Mutex不同, Semaphore没有“所有者” - 它与线程无关。任何线程都可以在信号量上调用Release,而使用Mutex和lock,只有获得锁的线程才能释放它。
初始值可用于启动可以同时授予的信号量的请求数。它为相关的sempahore设置了当前可用的并发级别。
尽管最大计数设置了可以同时授予的信号量的最大请求数。它设置了相关信号量的最大潜在并发性。
您不能将计数器CurrentCount
增加到大于初始化时设置的最大计数。
以下示例显示信号量如何与线程无关:
private static Semaphore semaphore = new Semaphore(3, 6);
private static void Main(string[] args)
{
//semaphore.Release(); //openning another slot for concurreny
semaphore.WaitOne();
Console.WriteLine("main0");
new Thread(() =>
{
semaphore.WaitOne();
Console.WriteLine("thread0");
semaphore.WaitOne();
Console.WriteLine("thread1");
Thread.Sleep(3000);
Console.WriteLine("uncomment the release line to make main1 get in");
}).Start();
Thread.Sleep(1000);
semaphore.WaitOne();
Console.WriteLine("main1");
Console.ReadKey();
}
有关详细信息,请查看http://www.albahari.com/threading/part2.aspx#_Semaphore
答案 2 :(得分:0)
与互斥锁不同,信号量可以在任何线程中释放()和WaitOne()。 WaitOne()—信号量递减计数器。如果counter == 0,则阻塞直到其增加。 Release()—信号量增量计数器。第二个构造函数参数==计数器,阻塞直到减小。