我有一个小程序作为下面的测试:
#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
然后它挂起而不再运行。代码在哪里出错了? 非常感谢。
答案 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_guard
和std::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,所以不知道确切名称)来避免这样的问题