在 c 中使用 POSIX 信号量的多线程
Multi threading using POSIX Semaphore in c
我正在尝试使用信号量从摄像机捕获帧并并行进行对象识别,我在这里有疑问:
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。
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.
你得到的是随机值,因为它们是这里的时间问题。为了确保线程已经启动并递减了信号量,我建议您等待 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);
我正在尝试使用信号量从摄像机捕获帧并并行进行对象识别,我在这里有疑问:
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。
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.
你得到的是随机值,因为它们是这里的时间问题。为了确保线程已经启动并递减了信号量,我建议您等待 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);