如何测试锁内的等待线程

本文关键字:等待 线程 何测试 测试 | 更新日期: 2023-09-27 18:11:07

所以我知道您可以使用信号量和可能的其他方法来确定锁是否会成功和/或有多少线程正在等待锁,但是您可以在锁本身内做到这一点吗?

我的情况是我有一个事件处理程序,可以由List内的许多对象调用。在继续之前,我想在锁内做一个测试,看看所有对象是否都处于正确的状态。对象转换到适当的状态,然后引发此事件,因此在单线程模型中,当最后一个线程引发此事件时,所有对象将处于正确的状态,然后我们继续。但我想到,有了多个线程,多个对象可能会转换到我正在检查的状态,但还没有处理这个事件,因为它们正在等待锁。因此,锁内的条件状态检查将为真,但在所有线程完成处理此事件之前,继续将是坏的。我需要它只有在最后一个线程被处理时才为真,以确保我们不会太快进行。

例如在半真实的代码中:

object _LockObj = new object();
void Event_Handler(object sender, EventArgs e)
{
    MyObject originator = sender as MyObject;
    if(originator == null)
        return;
    *Do stuff with the originator*
    lock(_LockObj)
    {
        if(ListOfMyObjects.FindAll(o => o.State == DesiredState)
                          .Count == ListOfMyObjects.Count 
                                 && *nothing waiting at the lock*)
        {
            *Proceed*
        }
    }
}

我完全准备接受我的方法是臭的开始,我正在寻找的解决方案是没有意义的,如果我在第一个地方做得很好,但我不确定如何以线程安全的方式正确地做到这一点。

我打算在MyObject中添加更多的状态,并通过在*Do stuff with the originator*部分设置适当的状态来管理流,但从这里转换MyObject感觉不太正确,更不用说我必须为每个状态实现一个持有状态,这会引发一个越来越难闻的事件,而不是更简单!

所以如果有一个简单的方法来做'nothing waiting at the lock'检查,那么这就是我想要的方式,除非我错过了一个非常简单的实现模式,在这种情况下有帮助。

如何测试锁内的等待线程

首先,不幸的是,测试等待lock()语句的其他线程不会得到您想要的结果。例如,如果对象A、B和C已经转换到所需的状态,并引发了它们的事件,那么可能只对一个对象调用Event_Handler,比如在那个点上调用A。稍后,相同的处理程序将在某个时刻为B和C运行。因此,现在所有的对象都应该处于所需的状态,并且没有线程在锁处等待。不想"继续"。即使你这样做,你需要考虑,同样的事情可能会发生在B之后,然后再次发生在C,所以"proceed"可能会运行三次…

这是一个简单的建议,但您可以使用计数器来测试有多少对象实际引发了事件。如果计数器不能提供足够的信息,你也可以使用另一个列表。重要的是,无论您使用哪种方法,都只能在同一个_LockObj的锁内更新计数器/列表/其他机制。然后可能在proceed运行后重置该计数器。如果你需要访问其他地方的计数器,确保你使用相同的lock(_LockObj),这将确保你没有改变它,而在另一个临界区。

object _LockObj = new object();
int _counter = 0;
void Event_Handler(object sender, EventArgs e)
{
    MyObject originator = sender as MyObject;
    if(originator == null)
        return;
    *Do stuff with the originator*
    lock(_LockObj)
    {
        ++_counter;
        if (_counter == ListOfMyObjects.Count)
        {
            *Proceed*
            _counter = 0;
        }
    }
}

Edit:删除对象状态的冗余检查。

您考虑过一个简单的同步工作项队列吗?因此,当事件被引发时,它只是将处理排队,并且处理由单独的线程按顺序完成?