2010-05-25 65 views
0

我希望有两个线程。第一个线程1偶尔会调用下面的伪功能:如何多线程呢?

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. 
} 

第二个线程2是永远在下面的伪循环:

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. 
} 

什么是写这使得两个线程1和线程是最好的方式在有多个内核的机器上尽可能地保持忙碌。我想避免在一个线程中的通知和另一个线程的检测之间的长时间延迟。我试过使用pthread条件变量,但发现thread2正在执行'notify thread1 I busy'和while()onS2IsExclusive()中的waitForThread2()循环之间的延迟可能高达几乎一秒的延迟。然后我尝试使用一个易变的sig_atomic_t共享变量来控制它,但是出了问题,所以我不能正确地做到这一点。

+4

你会过得更好告诉人们,你实际上是试图解决,而不是要求他们执行你已经设想了一个解决问题的... – 2010-05-25 02:13:47

+0

伪代码并没有太大的意义。你如何通知另一个线程你忙?为什么?此外,你在这里关注线程;通常,您需要同步数据。你同步哪些数据,以及你的并行操作如何? – WhirlWind 2010-05-25 02:16:45

+0

如果你的condvars正在采取任何行动,你正在做的事情非常错误。此外,要做的规范是锁定数据结构,而不是“通知其他线程”;后者不会缩放。 – 2010-05-25 02:28:53

回答

1

我看起来像你试图做一个会合(一个短期来自阿达)。

第二个线程是坐着,等待第一个线程调用它,那么它马上做了一些工作,而第一个线程等待,和第一线后,一些更多的工作就完成了。

第一个线程正在“调用”第二个线程 - 如果第二个线程无法接听呼叫,立即超时。

阿达支持这种直接的语言,但假设移植到小梅是不是一种选择...

这可能有三个信号量来实现。信号量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 

注意:从头开始编写,未经测试。看起来比我想象的要复杂得多;我错过了什么吗?

+0

信号比使用条件变量和互斥锁更高效吗? – WilliamKF 2010-05-25 03:52:28

+0

更高效的代码行?不知道。运行时效率更高?与其他所有开销相比,我怀疑你能分辨出差异。如果代码中没有更好的地方进行优化,我会非常惊讶。 – Oddthinking 2010-05-25 11:54:32

3

好像你应该使用旗语发信号,而不是“而”循环闲置线程,等待出现一些状况。空闲循环是不好的。

+0

空闲循环真的是要解释这个想法,而不是真的以这种方式实施。我已经从问题中删除了他们,因为他们正在引起主要问题的分心。目前,这些是用条件变量实现的,没有超时。 – WilliamKF 2010-05-25 03:53:56

1

胜于让线程告诉对方“我很忙”或“我不忙”,再想想在你的对象线程上运行的数据方面。

如果有一些数据(比如,一个计数器)这两个线程可能试图同时改变,这意味着你需要一个互斥体存在。

当一个线程更改其他线程可能正在等待的共享数据状态时,发出一个条件变量的信号通知它们。 (例如,如果生产者线程将数据添加到队列中,它可能表示消费者可能正在等待的“dataAvailable”条件。)

+0

我认为这是问题的核心。 – WhirlWind 2010-05-25 02:31:55