c - 在c中使用POSIX Semaphore进行多线程

标签 c multithreading semaphore

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

ma​​in.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。

有人可以帮帮我吗,我对信号量的理解是否错误?

函数.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 .

关于c - 在c中使用POSIX Semaphore进行多线程,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/42524898/

相关文章:

c++ - 如何在c++/c中通过socks代理创建基本的TCP连接?

c - 阻塞当前线程,类似于 getchar()

c# - 定时信号量

c - 了解arm64的kvm_vcpu_run_vhe函数

c - 在C中用空字符分割字符串

c - 有多少空字节,在 C 中连接字符串

c - 信号量 unix c 等待零

c - 在 GTK+ 中进行语法高亮显示的最佳方式?

C#:数据表线程安全问题

multithreading - Ada95 中的线程和信号量