C pthread:如何在一段时间后唤醒它?
我想从另一个pthread唤醒一个pthread-但是过了一段时间。我知道signal或pthread_signal和pthread_cond_wait可以用来唤醒另一个线程,但我看不到一种方法来安排这个。情况可能是这样的:C pthread:如何在一段时间后唤醒它?,c,pthreads,signals,C,Pthreads,Signals,我想从另一个pthread唤醒一个pthread-但是过了一段时间。我知道signal或pthread_signal和pthread_cond_wait可以用来唤醒另一个线程,但我看不到一种方法来安排这个。情况可能是这样的: THREAD 1: ======== while(1) recv(low priority msg); dump msg to buffer THREAD 2: ======== while(1) recv(high priority msg
THREAD 1:
========
while(1)
recv(low priority msg);
dump msg to buffer
THREAD 2:
========
while(1)
recv(high priority msg);
..do a little bit of processing with msg ..
dump msg to buffer
wake(THREAD3, 5-seconds-later); <-- **HOW TO DO THIS? **
//let some msgs collect for at least a 5 sec window.
//i.e.,Don't wake thread3 immediately for every msg rcvd.
THREAD 3:
=========
while(1)
do some stuff ..
Process all msgs in buffer
sleep(60 seconds).
线程1:
========
而(1)
recv(低优先级消息);
将消息转储到缓冲区
线程2:
========
而(1)
recv(高优先级消息);
..用味精做一点处理。。
将消息转储到缓冲区
唤醒(线程3,5秒后) 为什么不将当前时间与之前保存的时间进行比较
time_t last_uncond_wakeup = time(NULL);
time_t last_recv = 0;
while (1)
{
if (recv())
{
// Do things
last_recv = time(NULL);
}
// Possible other things
time_t now = time(NULL);
if ((last_recv != 0 && now - last_recv > 5) ||
(now - last_uncond_wakeup > 60))
{
wake(thread3);
last_uncond_wakeup = now;
last_recv = 0;
}
}
您可以让唤醒的线程自己进行等待。在唤醒线程中:
pthread_mutex_lock(&lock);
if (!wakeup_scheduled) {
wakeup_scheduled = 1;
wakeup_time = time() + 5;
pthread_cond_signal(&cond);
}
pthread_mutex_unlock(&lock);
pthread_mutex_lock(&lock);
while (!wakeup_scheduled)
pthread_cond_wait(&cond, &lock);
pthread_mutex_unlock(&lock);
sleep_until(wakeup_time);
pthread_mutex_lock(&lock);
wakeup_scheduled = 0;
pthread_mutex_unlock(&lock);
在等待线程中:
pthread_mutex_lock(&lock);
if (!wakeup_scheduled) {
wakeup_scheduled = 1;
wakeup_time = time() + 5;
pthread_cond_signal(&cond);
}
pthread_mutex_unlock(&lock);
pthread_mutex_lock(&lock);
while (!wakeup_scheduled)
pthread_cond_wait(&cond, &lock);
pthread_mutex_unlock(&lock);
sleep_until(wakeup_time);
pthread_mutex_lock(&lock);
wakeup_scheduled = 0;
pthread_mutex_unlock(&lock);
如何使用pthreadapi提供的pthread\u cond\t
对象?
您可以在线程中共享这样一个对象,并让它们对其进行适当的操作。
生成的代码应如下所示:
/*
* I lazily chose to make it global.
* You could dynamically allocate the memory for it
* And share the pointer between your threads in
* A data structure through the argument pointer
*/
pthread_cond_t cond_var;
pthread_mutex_t cond_mutex;
int wake_up = 0;
/* To call before creating your threads: */
int err;
if (0 != (err = pthread_cond_init(&cond_var, NULL))) {
/* An error occurred, handle it nicely */
}
if (0 != (err = pthread_mutex_init(&cond_mutex, NULL))) {
/* Error ! */
}
/*****************************************/
/* Within your threads */
void *thread_one(void *arg)
{
int err = 0;
/* Remember you can embed the cond_var
* and the cond_mutex in
* Whatever you get from arg pointer */
/* Some work */
/* Argh ! I want to wake up thread 3 */
pthread_mutex_lock(&cond_mutex);
wake_up = 1; // Tell thread 3 a wake_up rq has been done
pthread_mutex_unlock(&cond_mutex);
if (0 != (err = pthread_cond_broadcast(&cond_var))) {
/* Oops ... Error :S */
} else {
/* Thread 3 should be alright now ! */
}
/* Some work */
pthread_exit(NULL);
return NULL;
}
void *thread_three(void *arg)
{
int err;
/* Some work */
/* Oh, I need to sleep for a while ...
* I'll wait for thread_one to wake me up. */
pthread_mutex_lock(&cond_mutex);
while (!wake_up) {
err = pthread_cond_wait(&cond_var, &cond_mutex);
pthread_mutex_unlock(&cond_mutex);
if (!err || ETIMEDOUT == err) {
/* Woken up or time out */
} else {
/* Oops : error */
/* We might have to break the loop */
}
/* We lock the mutex again before the test */
pthread_mutex_lock(&cond_mutex);
}
/* Since we have acknowledged the wake_up rq
* We set "wake_up" to 0. */
wake_up = 0;
pthread_mutex_unlock(&cond_mutex);
/* Some work */
pthread_exit(NULL);
return NULL;
}
如果您希望线程3在超时后退出到代码> pthRead CONDYWAITE()/CUT>,请考虑使用<代码> pthRead CONDYTIDEMDEWAITE()/代码>(仔细阅读该人,您提供的超时值是绝对时间,而不是您不想超过的时间量)。
如果超时过期,pthread\u cond\u timedwait()
将返回一个ETIMEDOUT
错误
编辑:我跳过了锁定/解锁调用中的错误检查,请不要忘记处理此潜在问题
EDIT²:我在上面的代码中稍微检查了一下代码,每次我收到一条消息,“上次收到”和“现在”几乎是一样的。此外,我无法假设MSG何时会进入或停止进入。如果我只收到一条消息(比如说几分钟后,..),那么thread3在接下来的5秒钟内永远不会被唤醒。@G.A.如果你想无条件地每5秒钟醒来一次,我已经为此更新了我的伪代码。谢谢你的努力,Jaochim。如前所述,我不想无条件地每5秒唤醒一次。只有当其他线程接收到任何高优先级MSG时,才希望在5秒钟后将其唤醒。否则它应该在默认的60秒后唤醒。@G.A.现在呢?现在,wake
要么在接收后5秒调用,要么在60秒后无条件调用。pthread_cond_timedwait()。。。这是我需要探索的,它可能会奏效。在上面的代码中,thread1将广播条件信号,这将“立即”唤醒thread3。我想看看如何在一个小时间窗口后唤醒它。因此,一个小的修改应该是可行的。如果thread3从pthread_cond_TIMEDWAIT(60秒)唤醒,则在执行其余操作之前先休眠5秒。所以我会接受这个答案,因为它给了我足够的时间继续下去。但是,如果thread1在thread3已经从第一次广播中唤醒的情况下发送另一个_广播(&condvar)会发生什么情况?如果在没有线程卡在cond_wait-like函数中的情况下执行广播,则它没有效果。我所说的“无效”,是指一切都会发生,就好像你没有呼叫广播一样。