关键部分 - 只有单线程在锁定时“休眠”

Posted

技术标签:

【中文标题】关键部分 - 只有单线程在锁定时“休眠”【英文标题】:Critical Section - Only Single thread "sleeps" on lock 【发布时间】:2021-03-15 19:45:16 【问题描述】:

我有一个临界区(使用locked 范围)。

我希望只有最新传入的线程在其上“休眠”。因此 - 一旦关键部分被锁定,每个传入的线程都会“终止”所有之前的睡眠线程。

有没有办法使用 C# 来实现这一点?

谢谢

【问题讨论】:

lock 在后台使用Monitor 类,您可以尝试使用MonitorSemaphore 获得所需的行为 你能定义其他线程应该发生什么吗? @MoB。其他线程被GC终止并收集 【参考方案1】:

似乎最有效的机制是使用任务,所以下面的解决方案实际上是异步的,而不是同步的,因为这样代码就简单多了。如果您需要它是同步的,您可以同步等待任务。

public class SingleWaiterLock

    private bool realLockTaken = false;
    private TaskCompletionSource<bool> waiterTCS = null;
    private object lockObject = new object();

    public Task<bool> WaitAsync()
    
        lock (lockObject)
        
            if (!realLockTaken)
            
                realLockTaken = true;
                return Task.FromResult(true);
            
            if (waiterTCS == null)
            
                waiterTCS = new TaskCompletionSource<bool>();
                return waiterTCS.Task;
            
            else
            
                waiterTCS.SetResult(false);
                waiterTCS = new TaskCompletionSource<bool>();
                return waiterTCS.Task;
            
        
    

    public void Release()
    
        lock (lockObject)
        
            if (waiterTCS != null)
            
                waiterTCS.SetResult(true);
                waiterTCS = null;
            
            else
            
                realLockTaken = false;
            
        
    

从 wait 方法返回的布尔值指示您是实际获得了锁(如果它返回 true)还是被稍后的人启动(返回 false)。仅当等待返回 true 时才应释放(但必须始终释放)锁。

【讨论】:

以上是关于关键部分 - 只有单线程在锁定时“休眠”的主要内容,如果未能解决你的问题,请参考以下文章

多线程中的双重检查锁

redis

[UE4]UE4是单线程的吗?

pythonprocess多核更慢

最快实现单线程提供数据,多线程消费数据

用单线程 LMAX 编写