2012-12-05 79 views
2

everyone。 我是新来的信号量,最近我正在学习使用二进制信号量来实现一个简单的问题,我有一些问题。二进制信号量在C++中同步线程

所以有一个访问室,一次只有一个人可以进去。在我的设计中有三个人的队列(这是我创建的所有线程)。例如,在第二队列中的人访问该房间之后,下一个要进入房间的人是排在第三队列中的第一个人,而不是第一队列的人。给出总人数。离开后,只需简单地终止线程。

我想创建三个信号来处理这个问题,即在第二个队列中的一个人进入之后,然后阻塞第二个队列并且仅仅“发信号”第三个队列继续。等等等等。但是,代码有一些问题。这里我只是展示一些信号量代码的一部分。

INT主:

sem_init(&互斥,0,1);

sem_init(& s0,0,1);

sem_init(& s1,0,1);

sem_init(& s2,0,1);

//创建100个并行线程和随机投入在线程函数队列0或队列1或队列2

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

尝试在等待之前放置打印语句,并告诉我您看到了什么。 – Xymostech

+0

它只是阻止,只显示一个线程正在访问,然后主要完成。我只是想知道thread_function的设计是否存在任何问题? – user1878173

+0

你的'queueId'和'queue_Num'是如何定义的? – Xymostech

回答

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; 

    .. 
} 

在此之后,你的代码对我来说很好。

+0

输出只显示“person1正在访问”,然后程序结束......其他线程的状态如何?我创建了10个线程进行测试,它应该弹出10次,告诉我哪个人进入..时间..或者你可以离开你的联系人,也许电子邮件地址,我可以发送代码给你看看 – user1878173