【问题标题】:Log collisions in multithreading在多线程中记录冲突
【发布时间】:2019-05-08 10:26:08
【问题描述】:

我想用这个简单的代码记录多线程中的冲突

    public T DataRef
    {
        get
        {
            Collisions.DetectAndSaveCollision(typeof(T).ToString(), Sync);
            lock (Sync)
            {
                return _tData;
            }
        }
        set
        {
            IsInitialized = true;
            Collisions.DetectAndSaveCollision(typeof(T).ToString(), Sync);
            lock (Sync)
            {
                _tData = value;
            }
        }
    }

这是在碰撞列表中添加元素的方法

    public static void DetectAndSaveCollision(string value, object lockObject)
    {
        var acquired = false;
        try
        {
            acquired = Monitor.TryEnter(lockObject);
        }
        finally
        {
            if (acquired)
            {
                Monitor.Exit(lockObject);
            }
            else
            {
                lock (lockObject)
                {
                    CollisionCollection.Add(Thread.CurrentThread, value);
                }
            }
        }
    }

但我不确定它是否没有死锁

【问题讨论】:

  • 我没有看“无死锁”,但这有一个竞争条件。如果在您调用 DetectAndSaveCollision 时没有人获得锁,但另一个线程尝试在 同时 DetectAndSaveCollision 获得锁,则其他线程将等待,然后当 DetectAndSaveCollision 释放锁时,其他线程将抢它。 DetectAndSaveCollision 然后会返回到外面的代码。基本上,我不确定你想在这里做什么,但不是这样。
  • 您能告诉我们您在这里要解决的问题吗?为什么你需要以某种方式检测“碰撞”呢?锁应该确保两个线程不会以冲突的方式访问相同的共享状态,这不适合你吗?那么如果一个线程必须在第一个线程完成之前等待几毫秒呢?
  • 只有 1 个锁就很难造成死锁情况,我只是不确定这段代码是否符合您的想法。

标签: c# .net multithreading locking


【解决方案1】:

这是无死锁的,因为最多同时获得一个锁。

正如 Lasse 在 cmets 中指出的那样,这里存在竞争条件,因为您连续两次获得 Sync 锁。所以数据不会很准确。如果近似数据对您来说足够了,那么这很好。

您可以通过在获得锁时不立即释放锁来修复竞争。像这样的:

var acquiredImmediately = Monitor.TryEnter(...); //test lock

if (!acquiredImmediately) {
    Log(...);
    Monitor.Enter(...); //retry by blocking
}

CriticalRegion();

Monitor.Exit();

当然,这需要finally 的保护。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-12-15
    • 2018-07-02
    • 1970-01-01
    • 2013-06-13
    • 1970-01-01
    相关资源
    最近更新 更多