在c中使用POSIX信号量的多线程

时间:2017-03-01 06:41:14

标签: c multithreading semaphore

我正在尝试使用信号量从摄像机捕获帧并同时进行对象识别,我对此有疑问:

main.c 包含修改

sem_t sem_1;
sem_init(&sem_1, 0, 1);  //Initial value of 1
sem_init(&sem_2, 0, 1);  //Initial value of 1

int val_sem1,val_sem2;
sem_getvalue(&mutex_ping1, &val_sem1);
printf("%d %d \r\n", val_sem1,val_sem2);   //Output = 1 1(Correct)

//Create thread
trc = pthread_create(&tid_1, NULL, objrecognition_2, &obj_num[0]);
trc = pthread_create(&tid_2, NULL, objrecognition_3, &obj_num[1]);

Sleep(5000);


 sem_getvalue(&sem_1, &val_sem1);
 sem_getvalue(&sem_2, &val_sem2);
 printf("%d %d \r\n", val_sem1,val_sem2);  //Ideal output? 

 //Few line of code

while(1)
{
   //Get camera frame from video camera
   ....
   ....

   frame[index%3] = currentframe; //Using 3 backup buffers to avoid race around


   //For the very first time always sem_post(logic to keep index > index_use)
   if ((check))   //Initial value of check =1
  {
      check = 0;//Check is made 0 here after permanently
      sem_post(&sem1);
      sem_post(&sem2);
  }


   sem_getvalue(&sem_1, &val_sem1);//Get the present semaphore1 value
   sem_getvalue(&sem_2, &val_sem2);//Get the present semaphore2 value


   //This part of the code is activated from the second run because of check variable

   //Check if thread has completed one loop run and is waiting on sem_wait()
   if ((val_sem_1 == 0) &&  (val_sem_2 == 0) && (check==0)) //Checking if thread has completed one loop run
   {
     index_use++;    //The thread uses frame[index_use % 3] to process 
                    //so that it does not collide with frame[index % 3]
     sem_post(&sem_1);
     sem_post(&sem_2);
   }

   index++;
}

输出应为0,因为线程中的sem_wait(在 functions.c 下面)必须将值递减为0并且应该被阻止

但是我得到的是随机输出,例如1,-1,有时是0。

有谁能帮帮我,我对信号量的理解是错误的吗?

functions.c

void*  objrecognition_2(void* arg2)
{
   while (1)
  {

    sem_wait(&mutex_ping2);

   ...
   ...
  }
}

编辑

我在调用sem_post()之前设置了一个断点,并在创建线程后保持5秒的延迟。

因此线程被创建并且必须将信号量递减1并变为零并且应该等待直到sem_post()被激活。

现在它在第二个printf处仅打印-1。

2 个答案:

答案 0 :(得分:4)

来自documentation

  

如果一个或多个进程或线程被阻塞等待锁定   信号量与sem_wait(3),POSIX.1允许两种可能性   在sval中返回的值:返回0; 或负数   其绝对值是进程数的计数   sem_wait(3)中当前被阻止的线程。 Linux采用前者   行为。

所以价值不是随机的,它有意义。在您的特定示例代码中:

  • -1表示objrecognition_2再次调用sem_wait而不调用sem_post。所以它处于僵局。

  • 0表示objrecognition_2尚未自行陷入僵局。

  • 1表示objrecognition_2尚未在信号量上调用sem_wait

在我对我的回答的评论中进行编辑和讨论之后,我很清楚你正试图自己实现一个线程障碍。我建议你只使用pthread barrier implementation instead

答案 1 :(得分:0)

你得到的是随机值,因为这是一个时间问题。为了确保线程已经启动并减少信号量,我建议你等待1秒钟,看看下面的代码:

//After say 20 lines of code, such that the thread actually gets created

// put the main thread to sleep for 1 second as 
// 20 lines of code may not be too much to give 
// the opportunity to another thread to work and capture the semaphore.

sem_getvalue(&mutex_ping1, &val_sem1);