【问题标题】:Pthread: wake a thread from 4 threadspthread:从4个线程中唤醒一个线程
【发布时间】:2022-11-03 16:02:51
【问题描述】:

我在唤醒 C++ 中的线程时遇到问题。我有 4 个正在运行的线程。我想在 4 个正在运行的线程完成后唤醒我的睡眠线程。我用条件等待操作做到了,但看起来不太好。我怎样才能以更好的质量方式完成这个过程?

4 个任务由广播触发,同时开始在不同的内核上工作。在每个任务结束时,它将自己的taskID的标志设置为1,并向睡眠任务发送信号。处于睡眠状态的任务每收到一个信号就会被唤醒,并检查每个任务的标志。如果 4 任务标志为 1,它继续并做自己的工作。

void *thread_sleep( void *arg )
{
    pthread_mutex_lock(&mutex_sleep);
    
    while(flag_task[0] == 0 || flag_task[1] == 0 || flag_task[2] == 0 || flag_task[3] == 0)
        pthread_cond_wait(&cond_sleep, &mutex_sleep);
    
    /*
        .
        .
        .
        .   
    */
        
    flag_task[0] = 0;
    flag_task[1] = 0;
    flag_task[2] = 0;
    flag_task[3] = 0;
    
    pthread_mutex_unlock(&mutex_sleep);
}


void *thread( void *arg)
{
    int taskID = *(char *)arg - '0';

    while(1)
    {
        pthread_mutex_lock(&mutex[taskID]);
        pthread_cond_wait(&cond, &mutex[taskID]);
        /*
            .
            .
            .
            .
        */
        pthread_mutex_unlock(&mutex[taskID]);
        flag_task[taskID] = 1;
        pthread_cond_signal(&cond_sleep);
    }
}

int main()
{
    pthread_create( &pthread1, NULL, thread, (void *)"0" );
    pthread_create( &pthread2, NULL, thread, (void *)"1" );
    pthread_create( &pthread3, NULL, thread, (void *)"2" );
    pthread_create( &pthread4, NULL, thread, (void *)"3" );
    pthread_create( &pthread5, NULL, thread_sleep, (void *)"4" );
    
    pthread_cond_broadcast(&cond);
}

【问题讨论】:

  • 任务线程是否应该等到它们的标志被清除?或者如果任务线程多次设置标志而没有唤醒主线程会发生什么?我想你可能正在寻找a barrier
  • 按照设计,每秒运行一次 4 个任务。 4任务一结束,sleep任务就被唤醒,执行一个短暂的操作。例如,我从 main 广播。正常情况下,控制器将进程计算为 4 个任务的结果,并在 1 秒后再次广播。
  • 好的,但是如果在线程再次运行之前它没有完成它的任务会发生什么?是否强制执行?

标签: c++ multithreading pthreads mutex


【解决方案1】:

我用屏障解决了。谢谢@Quimby。

void *thread_sleep( void *arg )
{
    pthread_mutex_lock(&mutex_sleep);
    pthread_cond_wait(&cond_sleep, &mutex_sleep);
    /*
        .
        .
        .
        .   
    */ 
    pthread_mutex_unlock(&mutex_sleep);
}


void *thread( void *arg)
{
    int taskID = *(char *)arg - '0';

    while(1)
    {
        pthread_mutex_lock(&mutex[taskID]);
        pthread_cond_wait(&cond, &mutex[taskID]);
        /*
            .
            .
            .
            .
        */
        pthread_mutex_unlock(&mutex[taskID]);
        pthread_barrier_wait(&barrier);
        pthread_cond_signal(&cond_sleep);
    }
}

int main()
{
    pthread_barrier_init(&barrier, NULL, 4);
    
    pthread_create( &pthread1, NULL, thread, (void *)"0" );
    pthread_create( &pthread2, NULL, thread, (void *)"1" );
    pthread_create( &pthread3, NULL, thread, (void *)"2" );
    pthread_create( &pthread4, NULL, thread, (void *)"3" );
    pthread_create( &pthread5, NULL, thread_sleep, (void *)"4" );
    
    sleep(1);
    pthread_cond_broadcast(&cond);
}

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2018-10-13
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-03-18
    • 2019-12-04
    • 2013-06-04
    • 1970-01-01
    相关资源
    最近更新 更多