pthread 广播然后等待?

nok*_*oko 5 c++ mutex pthreads race-condition

我正在尝试设置几个线程以处于等待状态,直到它们收到pthread_cond_broadcast().

完成工作后,我希望线程回到等待状态。

我还希望调用 的进程pthread_cond_broadcast()在继续之前等待所有线程返回到它们的等待状态。在这种情况下,调用广播的是 main() 函数。我正在尝试使用 main(0pthread_cond_wait()在调用广播后执行 a 来执行此操作。

void* Work::job(void* id)
{
    int idx = (long)id;

    while(1)
    {
        pthread_mutex_lock(&job_lock);

        while(!jobs_complete)
        {
            // wait for main to broadcast
            pthread_cond_wait(&can_work, &job_lock);
            pthread_mutex_unlock(&job_lock);

            // work here

            pthread_mutex_lock(&job_lock);
            ++jobs_completed;

            if(jobs_completed == NUM_THREADS)
            {
                jobs_complete = true;
                pthread_cond_signal(&jobs_done);
                pthread_mutex_unlock(&job_lock);
            }
            pthread_mutex_unlock(&job_lock);
        }

        pthread_mutex_unlock(&job_lock);
    }

    return NULL;
}
Run Code Online (Sandbox Code Playgroud)

NUM_THREADS是 4,job_lock是一个pthread_mutex_tcan_workjobs_donepthread_cond_tjobs_completed是一个,booljobs_complete是一个int

// work

jobs_completed = false;
jobs_complete = 0;
pthread_mutex_lock(&job_lock);
pthread_cond_broadcast(&can_work);
pthread_cond_wait(&jobs_complete);
pthread_mutex_unlock(&job_lock);

// work that depends on jobs_complete
Run Code Online (Sandbox Code Playgroud)

现在,我正在通过调用pthread_cond_broadcast()然后立即调用来执行此操作pthread_cond_wait(),但这似乎陷入僵局。

任何人都可以解释我应该如何做或我哪里出错了?我很感激任何帮助。

谢谢!

did*_*erc 1

pthread_mutex_unlock在函数末尾可能有 3 次连续调用,这将导致未定义的行为。你实际上不需要两个内部的。如果jobs_completetrue,线程将退出循环并释放锁,否则它将循环并需要它来等待条件can_work

还有,还有

 pthread_cond_wait(&jobs_complete);
Run Code Online (Sandbox Code Playgroud)

你可能的意思是:

pthread_cond_wait(&jobs_complete,&job_lock);
Run Code Online (Sandbox Code Playgroud)

此外,该函数需要 apthread_cond_t *和 a pthread_mutex_t *,而不是 an int,所以即使这样,该代码也明显被破坏了。

请注意,条件变量上的信号或广播只会对已经等待该变量的线程产生影响。该信号不会保留以供将来等待。因此,当线程在jobs_completewhile 块上循环并再次等待时,必须再次向它们发出信号以恢复工作。

job_complete另一件事:您提到了asintjob_completedas的类型bool,但您的代码似乎并不同意:

        if(jobs_completed == NUM_THREADS)
        {
            jobs_complete = true;
Run Code Online (Sandbox Code Playgroud)

我的建议是:学习信号量和屏障抽象模型,如果可以的话,使用现有的实现(booststdC++11 中的实现),或者使用pthreadAPI 重新实现它们。这些将帮助您比操作 cond 变量更轻松地处理这种情况。在这个网站上查找现有的解决方案。例如,这个问题处理一个非常相似的问题,我提供的解决方案可以轻松修改以使用 pthread API 来满足您的要求。