2

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)

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

But I am getting random outputs such as 1, -1 and sometimes 0.

Could anyone please help me out here, Is my understanding of semaphores wrong??

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.

Hence the thread gets created and has to decrement semaphore by 1 and become zero and should wait untill sem_post() gets activated.

Now it prints only -1 at the second printf.

2 Answers 2

4

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; 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.

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. So it's in a deadlock.

  • 0 means objrecognition_2 hasn't deadlocked itself yet.

  • 1 means objrecognition_2 didn't call sem_wait on the semaphore at all yet.


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.

Sign up to request clarification or add additional context in comments.

13 Comments

Why would sem_wait be called again , since initial semaphore value is 1, so sem_wait must decrement the semaphore value to 0 and go to wait mode till sem_post increments the semaphore value.
@NithinGA - In the code you posted you sem_wait at the start of a loop. And you don't show yourself calling sem_post. So in the next iteration, sem_wait will see that the semaphore is 0 and wait. The thread is deadlocked with itself.
Actually I have put a break point before calling sem post(Please check the edits)...Now in the thread the first statement is sem_wait...So if I allow 5 seconds after creating the thread and then print the value of semaphore value, It has to get blocked at sem_wait right??
@NithinGA - Your edit doesn't have any call to sem_post in sight. Your code sample still has the same symptoms I described. If you want to discuss something about sem_post, then please post code that calls it.
@StorTeller, I have edited the question , does it give some clarity as to what I am doing
|
0

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:

//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);

1 Comment

Good Idea, I tried it, gave a 5 second delay to be safe, Now it is always -1, so as @StoryTeller pointed out it may be calling sem_wait() again and decrementing twice and hence -1 always...But why is this happening I do not understand

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.