首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >:如何在一段时间后唤醒它?

:如何在一段时间后唤醒它?
EN

Stack Overflow用户
提问于 2013-01-30 20:30:13
回答 3查看 3.6K关注 0票数 1

我想从另一个pthread中唤醒另一个pthread --但是过了一段时间。我知道带pthread_cond_wait的signal或pthread_signal可以用来唤醒另一个线程,但我看不到一种方法来调度它。情况会是这样的:

代码语言:javascript
复制
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). 

任何安排唤醒的简单方法(不是创建一个每秒唤醒的第四个线程,并决定是否有一个计划的条目让线程3唤醒)。如果队列中只有低优先级的消息,我真的不想频繁地唤醒线程3。此外,由于消息是以突发形式到来的(例如,在单个突发中有1000个高优先级消息),我不想为每个单独的消息唤醒线程3。它真的会让事情变慢(因为它每次醒来都会做一堆其他的处理工作)。

我使用的是一台ubuntu电脑。

EN

回答 3

Stack Overflow用户

回答已采纳

发布于 2013-01-30 21:01:18

如何使用可通过pthread API获得的pthread_cond_t对象?您可以在线程中共享这样的对象,并让它们对其进行适当的操作。

生成的代码应该如下所示:

代码语言:javascript
复制
/*
 * 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_cond_wait()的阻塞调用,请考虑使用pthread_cond_timedwait() (请仔细阅读手册,您提供的超时值是绝对时间,而不是您不想超过的时间量)。

如果超时时间到期,pthread_cond_timedwait()将返回ETIMEDOUT错误。

编辑:我跳过了锁/解锁调用中的错误检查,不要忘了处理这个潜在的问题!

EDIT²:我稍微回顾了一下代码

票数 2
EN

Stack Overflow用户

发布于 2013-01-30 20:36:21

为什么不将当前时间与之前保存的时间进行比较?

代码语言:javascript
复制
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;
    }
}
票数 0
EN

Stack Overflow用户

发布于 2013-01-30 20:44:02

你可以让唤醒线程自己来做等待。在唤醒线程中:

代码语言:javascript
复制
pthread_mutex_lock(&lock);
if (!wakeup_scheduled) {
    wakeup_scheduled = 1;
    wakeup_time = time() + 5;
    pthread_cond_signal(&cond);
}
pthread_mutex_unlock(&lock);

代码语言:javascript
复制
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);
票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/14604060

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档