我希望有两个主题。第一个thread1偶尔会调用以下伪函数:
void waitForThread2() {
if (thread2 is not idle) {
return;
}
notifyThread2IamReady(); // i.e. via 1st condition variable
Wait for thread2 to finish exclusive access. // i.e. via 2nd condition variable.
}
第二个thread2永远处于以下伪循环中:
for (;;) {
Notify thread1 I am idle.
Wait for thread1 to be ready. // i.e. via 1st condition variable.
Notify thread1 I am exclusive.
Do some work while thread1 is blocked.
Notify thread1 I am busy. // i.e. via 2nd condition variable.
Do some work in parallel with thread1.
}
写这个的最佳方法是使thread1和thread2在具有多个内核的机器上保持尽可能繁忙。我想避免一个线程中的通知和另一个线程的检测之间的长时间延迟。我尝试使用pthread条件变量,但发现thread2做'通知thread1我很忙'和在for2IsExclusive()上waitForThread2()中的循环之间的延迟可能达到差不多一秒的延迟。然后我尝试使用volatile sig_atomic_t共享变量来控制它,但是出了点问题,所以我一定不能正确地做。
答案 0 :(得分:3)
看起来你应该使用信号量来发送信号,而不是让“while”循环空闲线程,等待某些条件发生。空闲循环很糟糕。
答案 1 :(得分:1)
不要让你的线程告诉对方“我很忙”或“我不忙”,而是试着考虑你的线程正在操作的数据对象。
如果有一些数据(例如计数器),两个线程可能会同时尝试更改,这意味着您需要一个互斥锁。
当线程更改其他线程可能正在等待的共享数据状态时,请发出条件变量信号以通知它们。 (例如,如果Producer线程将数据添加到队列,它可能会发出“dataAvailable”条件的信号,消费者可能正在等待该条件。)
答案 2 :(得分:1)
我向你看,就像你正在尝试做一个约会(Ada的一个术语)。
第二个线程正在等待第一个线程调用它,然后它在第一个线程等待时立即执行一些工作,并在第一个线程完成后再执行一些工作。
第一个线程是“调用”第二个线程 - 如果第二个线程无法接听电话,则立即超时。
Ada直接在语言中支持这一点,但假设移植到Ada不是一个选项......
这可以用三个信号量实现。信号量1表示线程1准备好会合。信号量2表示线程2已准备好进行重新对话。信号量3表示会合已完成。
线程1:获取信号量1的默认值。
if Semaphore 2.acquire(timeout = 0) is successful # Thread 2 is ready
Semaphore 1.release() # Indicate I am ready
Semaphore 3.acquire() # Wait until the rendevous is complete.
Semaphore 3.release()
Semaphore 1.acquire() # Indicate I am not ready
Semaphore 2.release() # I am no longer using thread 2.
Do concurrent work
线程2:获取信号量2的默认值。
Loop forever
Semaphore 3.acquire() # Indicate Rendevous is not complete.
Semaphore_2.release() # Indicate I am ready
Semaphore_1.acquire() # Wait for Thread 1 to be ready
Joint processing
Semaphore 1.release() # I am no longer using thread 1.
Semaphore 3.release() # Rendevous is complete.
Semaphore 2.acquire() # I am not ready
Post-processing
注意:从头开始编写,未经测试。看起来比我想象的要复杂得多;我错过了什么吗?