我目前正在使用pthreads,我的一个线程中有一个run()方法。 run()方法检查向量的第一个元素的开始时间,并且需要执行阻塞睡眠,直到达到该时间,允许其他线程执行。问题是向量的前面元素可以更新,我需要在run()方法中重置计时器。我不确定如何解决这个问题。我不能使用睡眠,因为它将等到它上次检查的开始时间可能已经更新到更早的时间。
答案 0 :(得分: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);
顺便说一下,在我们的测试中,以这种方式睡眠和唤醒我们的线程比使用条件变量要快许多倍。
答案 1 :(得分:0)
无论更新什么,向量都需要以这种或那种方式向睡眠线程发出信号。有十几种方法可以做到这一点,但有两种显而易见的方法是条件变量,或者仅使用带有管道或类似物的select。
使用条件变量,您可以使用pthread_cond_timedwait
计算超时值。如果它超时,很好。如果您收到信号,则必须读取向量,重新计算超时,然后再次阻止。
与select()
类似,您在等待超时或管道上的某些输入时计算并使用向量和块中的超时值。无论更新向量的是什么,还会向管道写入内容并且线程会唤醒,重新计算等等...