大家。 我是信号量的新手,最近我正在学习使用二进制信号量实现一个简单的问题,我有一些问题。
所以有一个访问室,有一次只有一个人可以进去。在我的设计中有三个人的队列(这是我创建的所有线程)。例如,在第二个队列中的人访问该房间之后,下一个要进入房间的人是在第三个队列中等待的最高人,而不是第一个队列的人。给出了总人数。离开后,只需简单地终止线程。
我正在尝试创建三个信号量来处理这个问题,即在第二个队列中的一个人进入后,然后阻止第二个队列并且仅“发信号”第三个队列继续。等等。但是,代码存在一些问题。这里我只展示了代码的一些信号量部分。
主要在:
sem_init(& mutex,0,1);
sem_init(& s0,0,1);
sem_init(& s1,0,1);
sem_init(& s2,0,1);
//创建100 pthread并随机放入queue0或queue1或queue2
for(int i = 0; i<num_thread; i++){
pthread_t curr_thread;
if(queueId == 0){
queue0.push(curr_thread);
}else if(queueId == 1){
queue1.push(curr_thread);
}else if(queueId == 2){
queue2.push(curr_thread);
}
pthread_attr_t attr;
pthread_attr_init (&attr);
pthread_attr_setdetachstate (&attr, PTHREAD_CREATE_DETACHED);
pthread_create (&curr_thread, &attr, &thread_function, &queue_Num);
pthread_attr_destroy (&attr);
}
在线程函数中:
void* thread_function (void* arg){
sem_wait(&mutex);
int n = *((int*) arg);
if(n==0){
sem_wait(&s0);
cout << "person in queue" << n << " is visiting" << endl;
sleep(1);
if(!queue0.empty()){
queue0.pop();
}else{
n++;
}
sem_post(&s1);
}else if(n==1){
sem_wait(&s1);
cout << "person in queue" << n << " is visiting" << endl;
sleep(1);
if(!queue1.empty()){
queue1.pop();
}else{
n++;
}
sem_post(&s2);
}else if(n==2){
sem_wait(&s2);
cout << "person in queue" << n << " is visiting" << endl;
sleep(1);
if(!queue2.empty()){
queue2.pop();
}else{
n++;
}
sem_post(&s0);
}
sem_post(&mutex);
return NULL;
}
实际上当我运行它时,似乎遇到了“死锁”,主要完成每次只显示2个线程。我认为在设计thread_function时一定存在一些问题。是否有人可以帮助指出并告诉我如何解决它?谢谢你。
答案 0 :(得分:0)
当您将queueId
传递给线程时,您不希望将指针传递给您的一个局部变量,因为您将很快更改它。你应该只是将整数本身传递给你的线程:
pthread_create(&curr_thread, &attr, &thread_function, (void*)queueId);
// Pass queueId the int, not a pointer
然后,当你需要读取线程中的值时,只需将void*
强制转换为整数:
void* thread_function (void* arg){
...
int n = (long)arg;
..
}
在此之后,对我来说,你的代码效果很好。