嗨,我在寻找以下问题的答案时遇到问题。我正在尝试在 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() 会按需要工作吗?如果没有,我必须把它放在锁里吗?如果没有,还有其他方法可以解决这个问题吗?
对不起,文字墙,并提前感谢您的回复。