【问题标题】:pthread_cond_wait and pthread_mutex_lock doesnt work as expectedpthread_cond_wait 和 pthread_mutex_lock 没有按预期工作
【发布时间】:2016-08-13 08:25:50
【问题描述】:

我创建了一个 ThreadPool 类和一个名为 execute_thread_helper() 的 void 函数,该函数在 void* execute_thread(void* arg) 内部调用(它以这种方式提供给线程的函数:ret = pthread_create(&workers[i], NULL, execute_thread, (void*)this);

void ThreadPool::execute_thread_helper()
{
    Task task;

    pthread_mutex_lock(&mutex);

    while(TaskList.empty()) // Previously "if"
    {
        cout << "Thread #"  << pthread_self() << " is blocked. "<< endl;
        pthread_cond_wait(&conditionVar, &mutex);
    }

    task = TaskList.front();
    TaskList.pop();

    cout << "Thread #"  << pthread_self() << " going to run the function. "<< endl;

    threadFunction(task);

    pthread_mutex_unlock(&mutex);
}

以这种方式将任务添加到任务队列中 -

void ThreadPool::add_task(Task newTask)
{    
    pthread_mutex_lock(&mutex);

    TaskList.push(newTask);    
    pthread_cond_signal(&conditionVar); 

    pthread_mutex_unlock(&mutex);

}

据我了解,一旦创建了一个线程,它就会尝试运行execute_thread。然后,给定一个空队列,我希望pthread_cond_wait“让”线程进入睡眠状态(并对所有创建的线程执行此操作),直到它被add_task 中的pthread_cond_signal 唤醒。

嗯..我尝试在单个线程上检查程序,并得到了这个结果(我没有add_task。只是试图创建池)-

Thread #139859560904448 is blocked. 
Thread #139859560904448 going to run the function. 
in map() key is   and value is 0 

我不明白线程是如何通过 if 语句的,如果它之前被搁置的话。

尝试创建 3 个线程池时的输出 -

Thread #140013458028288 is blocked. 
Thread #140013458028288 going to run the function. 
in map() key is   and value is 0 
Thread #140013458028288 going to run the function. 
in map() key is   and value is 0 
Thread #140013458028288 going to run the function. 
in map() key is   and value is 0 

为什么其他 2 个线程没有被搁置?

编辑

感谢 SergeyA,用 while 切换 if 确实有帮助。 但是,尝试创建 3 个线程池,结果还是这样 -

Thread #139916558706432 is blocked. 
Thread #139916558706432 is blocked. 
Thread #139916558706432 is blocked. 
Thread #139916558706432 is blocked. 
Thread #139916558706432 is blocked. 
Thread #139916558706432 is blocked. 
Thread #139916558706432 is blocked. 
Thread #139916558706432 is blocked. 

为什么没有创建其他线程?它们不是都应该被创建、同时运行并交替打印它们被阻止的吗?

【问题讨论】:

  • pthread_mutex_lock(&amp;mutex); //mutex lock - 为什么不pthread_mutex_lock(&amp;mutex); //pthread_mutex_lock?后一种形式会使代码更清晰,不是吗?

标签: c++ multithreading pthreads threadpool


【解决方案1】:

pthread_cond_signal(&amp;conditionVar); 只会唤醒一个等待的线程。如果您的任务足够短,您将偶然总是唤醒同一个线程。没有公平。 :-)

您还可以使用pthread_cond_broadcast(&amp;conditionVar); 唤醒所有等待的线程。然后你应该看到你所有的线程总是被唤醒。但是对于您的线程池来说,应该不需要使用广播变体。

【讨论】:

    【解决方案2】:

    条件变量容易出现所谓的 *spurios 唤醒。这意味着代码是畅通的,但条件并没有真正改变,也没有发出信号。

    这就是为什么您总是必须循环调用wait 函数,并在每次唤醒后检查条件。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2017-11-08
      • 1970-01-01
      • 2013-07-07
      • 2012-12-05
      • 2017-05-22
      • 2019-07-28
      • 2014-05-24
      • 1970-01-01
      相关资源
      最近更新 更多