2

我目前正在使用 pthreads,并且我的一个线程中有一个 run() 方法。run() 方法检查向量的第一个元素的开始时间,并且需要进行阻塞睡眠,直到达到该时间,从而允许其他线程执行。问题是向量的前面元素可以更新,我需要在我的 run() 方法中重置计时器。我不确定如何处理这个问题。我不能使用睡眠,因为它会等到它最后一次检查的开始时间可能已经更新到更早的时间。

4

2 回答 2

1

您可以使用 pthread_kill() 唤醒在 sigtimedwait() 处休眠的特定线程。

sigset_t _fSigMask; // global sigmask

我们在创建线程之前执行此操作。线程从创建它们的线程继承其信号掩码。我们使用 SIGUSR1 给我们的线程发信号。其他信号可用。

sigemptyset(&_fSigMask);
sigaddset(&_fSigMask, SIGUSR1);
sigaddset(&_fSigMask, SIGSEGV);

然后休眠一个线程:

int nSig;
struct timespec tmTimeout = { nSec, nNanoSec }; // from your vector of times
sigtimedwait(&fSigMask, &nSig, &tmTimeout);

然后唤醒线程 pThread,只需发出信号:

pthread_kill(pThread, SIGUSR1);

顺便说一句,在我们的测试过程中,以这种方式休眠和唤醒我们的线程比使用条件变量快很多倍。

于 2012-05-10T01:49:15.040 回答
0

无论更新向量,都需要以一种或另一种方式向睡眠线程发出信号。有十几种方法可以做到这一点,但两种明显的方法是条件变量或仅使用带有管道或类似方法的 select。

使用条件变量,您可以使用pthread_cond_timedwait计算出的超时值。如果超时就好了。如果你收到信号,你必须读取向量,重新计算超时,然后再次阻塞。

同样,select()您在等待超时或管道上的某些输入时计算并使用向量和块中的超时值。无论是在更新向量,也会向管道写入一些内容,然后线程会唤醒、重新计算等等……

于 2012-05-10T00:32:58.677 回答