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

本文关键字:请求 了解 信号量 | 更新日期: 2023-09-27 18:25:45

我正在学习 c# 信号量,但有一点不明白。我可以像这样初始化信号量:

var semaphore = new Semaphore(4, 6);

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

如果要为调用线程保留一些插槽,可以 因此,通过使第一个参数小于第二个参数。

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

var semaphore = new Semaphore(0, 6);

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

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

我喜欢Albahari的解释:

信号灯就像一个夜总会:它有一定的容量,由保镖强制执行。一旦满员,就不能再有人进入,外面排起了长队。然后,对于每个离开的人,一个人从队列的头部进入。构造函数至少需要两个参数:夜总会当前可用的位置数和俱乐部的总容量。

与锁(监视器(和互斥不同,信号量没有"所有者">——它与线程无关。任何线程都可以在信号量上调用 Release,而对于互斥和锁,只有获得锁的线程才能释放它。

初始值可用于启动可同时授予的信号量请求数。 它为相关 Senpahore 设置当前可用的并发级别。

而最大计数设置可以同时授予的信号灯的最大请求数。 它设置相关信号灯的最大潜在并发性。

不能将计数器递增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

与互斥锁不同,信号量可以在任何线程中 Release(( 和 WaitOne((。WaitOne(( — 信号量递减中的计数器。如果计数器 == 0,则阻止直到它增加。Release(( — 信号增量中的计数器。第二个构造函数参数 == 计数器,直到它减少。