信号量:了解初始和最大请求​​数

时间:2014-10-05 13:34:46

标签: c# multithreading semaphore

我正在学习c#信号量,并且不了解一点。我可以像这样初始化Semaphore:

var semaphore = new Semaphore(4, 6);

在很多地方都有这样的解释:

  

如果你想为调用线程保留一些插槽,你可以这样做   所以通过使第一个参数小于第二个参数。

这是否意味着只有主线程可以使用剩余的2个资源槽?这是否意味着如果我这样写:

var semaphore = new Semaphore(0, 6);

只有主线程可以使用全部6个插槽?

3 个答案:

答案 0 :(得分:2)

我喜欢Albahari's explanation

  

信号量就像一个夜总会:它具有一定的容量,由保镖强制执行。一旦它满了,没有更多人可以进入,并且队列在外面建立起来。然后,对于每个离开的人,一个人从队列的头部进入。构造函数至少需要两个参数:夜总会当前可用的地点数量和俱乐部的总容量。

答案 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()—信号量增量计数器。第二个构造函数参数==计数器,阻塞直到减小。