[英]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.