0

嗨,我在寻找以下问题的答案时遇到问题。我正在尝试在 Linux 上实现一个应用层驱动程序,它执行一些 IO 但需要有一些非阻塞接口函数。本质上,这个环境中只有两个线程,线程 A 和 B。

考虑以下示例:

Class Driver
{
    void foo()
    {
        emergency_shutdown = true;
        Signal(cond)
    }

    void thread_loop()
    {
        Lock(cond)
        while (true)
        {
            if (emergency_shutdown)
            {
                // Do an atomic IO Operation #1 that could take 5ms
                // For example: Send an emergency shutdown packet
                emergency_shutdown = false;
            }
            else
            {
                // do an atomic IO Operation #2 that could take 100ms
            }
            Signal(cond)
            CondWait(cond, 1000); // 1 second wait.
        }
        Unlock(cond)
    }
}        


Class HigherLayer
{
    ...

    powerfail_handler() // Function only has 20ms to run before power is lost
    {
        // POWER FAIL DETECTED!
        // Do some important stuff

        Driver::foo() // Force shutdown of device

        // Do some other important stuff

        // ... Power eventually lost but hopefully we did all the
        // important stuff in this function.
    }

    ...
}

在上面的例子中..线程A基本上是运行'thread_loop()'的驱动程序线程,线程B是HigherLayer线程,它会做很多事情,如果检测到电源故障,它也会调用powerfail_handler。

主要问题是:驱动函数 foo() 可以在没有先锁定 cond 的情况下调用 Signal(cond) 吗?我不想 Lock cond 的原因是因为我不希望 powerfail_handler 调用 foo() 并且它必须等待 100ms 等待释放锁的任何可能情况。

我了解在 Lock 之外修改“emergency_shutdown”变量的后果。他们不会让我太担心。

我也明白在某些情况下,如果 foo() 在 IO 操作 #2 由线程 A 完成的 100 毫秒窗口期间被调用,那么我想要的 IO 操作 #1 将不会发生(因为在出现之前会失去电源)有机会做到这一点)。这也很好,我没有办法解决这个问题,只能忍受它,但在那种情况下,我不想被 foo() 阻止而错过在线程 B 中做“其他重要的事情”(其中这就是为什么我在 foo()) 中没有锁定。

我只是想确保如果线程 A 正在等待(90% 的时间应该是这种情况),我想发出信号停止等待并执行 IO 操作 #1。

那么 foo() 中的 Signal() 会按需要工作吗?如果没有,我必须把它放在锁里吗?如果没有,还有其他方法可以解决这个问题吗?

对不起,文字墙,并提前感谢您的回复。

4

1 回答 1

0

驱动程序函数 foo() 可以在不先锁定 cond 的情况下调用 Signal(cond) 吗?

在不持有互斥锁的情况下调用是好的pthread_cond_broadcast()可移植的:pthread_cond_signal()

无论线程当前是否拥有调用 pthread_cond_wait() 或 pthread_cond_timedwait() 的线程在等待期间与条件变量相关联的互斥锁,线程都可以调用 pthread_cond_broadcast() 或 pthread_cond_signal() 函数;但是,如果需要可预测的调度行为,则该互斥锁应由调用 pthread_cond_broadcast() 或 pthread_cond_signal() 的线程锁定。


我了解在 Lock 之外修改“emergency_shutdown”变量的后果。他们不会让我太担心。

至少使用原子操作来获取/设置值,emergency_shutdown如果您不想使用互斥锁进行保护,原子操作不会阻塞您的线程。

于 2013-09-25T09:12:51.917 回答