我正在尝试使用信号量从摄像机捕获帧并同时进行对象识别,我对此有疑问:
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。
答案 0 :(得分:4)
如果一个或多个进程或线程被阻塞等待锁定 信号量与sem_wait(3),POSIX.1允许两种可能性 在sval中返回的值:返回0; 或负数 其绝对值是进程数的计数 sem_wait(3)中当前被阻止的线程。 Linux采用前者 行为。
所以价值不是随机的,它有意义。在您的特定示例代码中:
-1表示objrecognition_2
再次调用sem_wait
而不调用sem_post
。所以它处于僵局。
0表示objrecognition_2
尚未自行陷入僵局。
1表示objrecognition_2
尚未在信号量上调用sem_wait
。
在我对我的回答的评论中进行编辑和讨论之后,我很清楚你正试图自己实现一个线程障碍。我建议你只使用pthread barrier implementation instead。
答案 1 :(得分:0)
你得到的是随机值,因为这是一个时间问题。为了确保线程已经启动并减少信号量,我建议你等待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);