pthread_join()似乎导致挂起我的程序,它出错了哪里?

时间:2017-06-27 12:28:44

标签: c++ multithreading pthreads

我有一个小程序作为下面的测试:

#include<pthread.h>
#include<unistd.h>
#include<cassert>
#include<iostream>
using namespace std;
pthread_mutex_t mt;
pthread_t tid[2];
char* msg[]={"thread1","thread2"};
void* tf(void*arg){
    pthread_mutex_lock(&mt);
    cout<<(char*)arg<<endl;
    return NULL;
}
int main(){
    assert(0==pthread_mutex_init(&mt,NULL));
    cout<<"step1"<<endl;
    pthread_create(&tid[0],NULL,tf,msg[0]);
    pthread_create(&tid[1],NULL,tf,msg[1]);
    pthread_join(tid[0],NULL);
    cout<<"step4"<<endl;
    pthread_join(tid[1],NULL);
    return 0;
}

我在mac上运行它并打印出来:

step1
thread1
step4

然后它挂起而不再运行。代码在哪里出错了? 非常感谢。

3 个答案:

答案 0 :(得分:6)

pthread_mutex_lock

  

互斥引用的互斥锁对象应通过调用锁定   pthread_mutex_lock()如果互斥锁已被锁定,则调用   线程必须阻塞,直到互斥锁变为可用。

线程2永远等待mt解锁,因为你从未解锁它并且线程1锁定它,你应该在tf结束时解锁:

void* tf(void*arg){
    pthread_mutex_lock(&mt);
    cout<<(char*)arg<<endl;
    pthread_mutex_unlock(&mt);
    return NULL;
}

附注:如果您有权访问C ++ 11,请考虑使用std::mutex&amp;而是std::lock_guardstd::thread

答案 1 :(得分:3)

你应该调用pthread_mutex_unlock解锁互斥锁,然后让第二个线程完成工作:

void* tf(void*arg){
    pthread_mutex_lock(&mt);
    cout<<(char*)arg<<endl;
    pthread_mutex_unlock(&mt); // <=== here
    return NULL;
}

如果未执行解锁,则第二个线程将永远等待互斥锁,程序将“挂起”。

如果在程序中必须使用 pthreads ,那么您可以考虑编写一些 RAII 包装来避免此类错误。

答案 2 :(得分:1)

您应该解锁互斥锁以允许第二个线程执行tf()函数。现在由第一个线程锁定的互斥锁(第一个意味着第一个启动ft()执行)并且永远不会解锁。我还建议使用类似std :: lock_guard(从未使用过pthread_mutex_t,所以不知道确切名称)来避免这样的问题