简体   繁体   English

在C中使用POSIX信号量进行多线程

[英]Multi threading using POSIX Semaphore in c

I am trying to use semaphores to capture frames from the video camera and do object recognition in parallel , I have a doubt here: 我正在尝试使用信号量从摄像机捕获帧并并行进行对象识别,我对此有疑问:

main.c ( with edits ) 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++;
}

Output should be 0 since sem_wait in thread(in functions.c below) must have decremented the value to 0 and should have got blocked 输出应该为0,因为线程中的sem_wait(在下面的functions.c中)必须将该值减为0并且应该被阻塞

But I am getting random outputs such as 1, -1 and sometimes 0. 但是我得到的是随机输出,例如1,-1,有时是0。

Could anyone please help me out here, Is my understanding of semaphores wrong?? 任何人都可以在这里帮助我,我对信号量的理解错了吗?

functions.c functions.c

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

    sem_wait(&mutex_ping2);

   ...
   ...
  }
}

edits 编辑

I have put a break point before calling sem_post() and also keeping a 5 second delay after creating the thread. 我在调用sem_post()之前设置了一个断点,并且在创建线程之后还保留了5秒的延迟。

Hence the thread gets created and has to decrement semaphore by 1 and become zero and should wait untill sem_post() gets activated. 因此,线程被创建,并且必须将信号量减1并变为零,并应等待sem_post()被激活。

Now it prints only -1 at the second printf. 现在,它在第二个printf只打印-1。

From the 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; 如果一个或多个进程或线程被阻塞,等待通过sem_wait(3)锁定信号量,则POSIX.1允许在sval中返回值的两种可能性:返回0;否则返回0。 or a negative number whose absolute value is the count of the number of processes and threads currently blocked in sem_wait(3). 或一个负数,其绝对值是 sem_wait(3)中当前阻塞的进程和线程数的计数 Linux adopts the former behavior. Linux采用以前的行为。

So the value isn't random, it has meaning. 因此该值不是随机的,而是有意义的。 In your particular sample code: 在您的特定示例代码中:

  • -1 means objrecognition_2 calls sem_wait again without calling sem_post before. -1表示objrecognition_2再次调用sem_wait而不先调用sem_post So it's in a deadlock. 因此陷入僵局。

  • 0 means objrecognition_2 hasn't deadlocked itself yet. 0表示objrecognition_2尚未死锁。

  • 1 means objrecognition_2 didn't call sem_wait on the semaphore at all yet. 1表示objrecognition_2尚未对信号量调用sem_wait


Following your edits and discussion in the comments to my answer, it's clear to me you are trying to implement a thread barrier by yourself. 在对我的答案的评论中进行编辑和讨论之后,对我来说很明显,您正在尝试自己实现线程屏障。 I suggest you just use the pthread barrier implementation instead . 我建议您改用pthread barrier实现

You are getting random value as their is a timing issue here. 您正在获得随机值,因为它们是时间问题。 To make sure the thread already started and decremented the semaphore I suggest you to wait for 1 second see the code below: 为了确保线程已经启动并减少了信号量,建议您等待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);

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM