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

Multi threading using POSIX Semaphore in c

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

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。

来自documentation

If one or more processes or threads are blocked waiting to lock the semaphore with sem_wait(3), POSIX.1 permits two possibilities for the value returned in sval: either 0 is returned; or a negative number whose absolute value is the count of the number of processes and threads currently blocked in sem_wait(3). Linux adopts the former behavior.

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

  • -1 表示 objrecognition_2 再次调用 sem_wait 而不是之前调用 sem_post。于是陷入僵局

  • 0 表示 objrecognition_2 还没有死锁。

  • 1 表示 objrecognition_2 根本没有在信号量上调用 sem_wait


根据您对我的回答的评论中的编辑和讨论,我很清楚您正在尝试自己实施线程屏障。我建议你只使用 pthread barrier implementation instead.

你得到的是随机值,因为它们是这里的时间问题。为了确保线程已经启动并递减了信号量,我建议您等待 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);