c# - SemaphoreSlim 的超时是否违背了它自己的目的?

标签 c# multithreading semaphore

semaphore 的真正力量是:

Limits the number of threads that can access a resource or pool of resources concurrently

这是理解和清楚的。

但是我从来没有机会玩过 Wait 的重载,它接受一个超时整数,然而 - 这似乎允许多个线程进入临界区我已明确设置信号量一次不允许超过一个线程:

private readonly SemaphoreSlim _mutex = new SemaphoreSlim(1);

private void Main()
{
    Task.Run(() => DelayAndIncrementAsync());
    Task.Run(() => DelayAndIncrementAsync());
}

private void DelayAndIncrementAsync()
{
    _mutex.Wait(2000);

    try
    {
        Console.WriteLine(0);
        Thread.Sleep(TimeSpan.FromSeconds(5));
        Console.WriteLine(1);
    }
    finally
    {
        _mutex.Release();
    }
}

enter image description here

第一个线程正在进入互斥区,打印“0”,等待 5 秒,同时 2 秒后另一个线程也进入临界区?

问题

这不是违背了信号量的全部目的吗?

我会使用这个超时的现实生活场景是什么,特别是当基本规则是 -

"Semaphore = Limits the number of threads that can access a resource or pool of resources concurrently

最佳答案

您需要检查等待的返回值。基于超时的等待将尝试 2 秒来获取互斥锁,然后返回。您需要检查返回值是否为真(即您有互斥锁)。

编辑:另请记住,如果信号量可用,基于超时的等待将立即返回,因此您不能通过此技术使用它来防止代码中的无限循环。

private readonly SemaphoreSlim _mutex = new SemaphoreSlim(1);
void Main()
{

    Task.Run(()=>DelayAndIncrementAsync());
    Task.Run(()=>DelayAndIncrementAsync());
}
public   void  DelayAndIncrementAsync()
{
    if (_mutex.Wait(2000))
    {
        try
        {
            Console.WriteLine(0);
            Thread.Sleep(TimeSpan.FromSeconds(5));
            Console.WriteLine(1);
        }    
        finally
        {
            _mutex.Release();
        }
    } else {
        //oh noes I don't have the mutex
    }
}

关于c# - SemaphoreSlim 的超时是否违背了它自己的目的?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/32624497/

相关文章:

c - 多个客户端的 posix 共享内存

java - 等待子线程完成,而不引用该线程

c# - 我如何从 new Dictionary(int, List<Customer>); 之类的东西中选择一个列表?

c# - Entity Framework Core - LINQ 选择导航属性创建无效查询

c# - .Net 中的多线程

java - JVM 在尝试获取信号量时卡住

c# - C# 中的 UDP 适用于 Windows,但不适用于 Linux

java - 多个客户端同时访问服务器

java - 如何解决这个内存一致性错误?

ios - NSManagedObjectContext.performBlockAndWait() 在主线程/队列上运行 block