奇怪的 POSIX 信号量行为(卡在 Linux 上的 sem_wait 上)
Posted
技术标签:
【中文标题】奇怪的 POSIX 信号量行为(卡在 Linux 上的 sem_wait 上)【英文标题】:Strange POSIX semaphore behavior (stuck on sem_wait on Linux) 【发布时间】:2019-10-11 22:58:35 【问题描述】:我正在尝试解决一个涉及 POSIX 信号量的学校问题。我遇到了一个问题,我已将其范围缩小到此简化代码:
sem_t sem;
void parent()
printf("waiting...\n");
sem_wait(&sem);
printf("done!\n");
void child()
sem_post(&sem);
printf("go!\n");
exit(0);
int main()
sem_init(&sem, 1, 0);
if(!fork())
child();
parent();
sem_destroy(&sem);
exit(0);
在 Linux 中编译(使用gcc -Wall -pthread sems.c -o sems
)并运行此程序时,我得到以下输出(程序未完成执行):
waiting...
go!
因为我在子进程中调用sem_post(&sem)
,所以我希望父进程越过sem_wait(&sem)
,输出为:
waiting...
go!
done!
更奇怪的是,出于好奇,我尝试使用 CLion(Cygwin 编译器)在 Windows 上对其进行测试,并且程序按预期运行。我在这里错过了什么?
【问题讨论】:
【参考方案1】:来自man page of sem_init()
:
如果 pshared 不为零,则信号量在进程之间共享,并且应该位于共享内存区域中(请参阅 shm_open(3)、mmap(2) 和 shmget(2))。 (由于 fork(2) 创建的子代继承了其父代的内存映射,它也可以访问信号量。)
您的sem
变量未在共享内存中分配;因此,尽管pshared
参数不为零,但它不能在进程之间共享。每个进程都有自己独特的信号量实例。
【讨论】:
@cabralpinto Cygwin 做了各种奇怪的事情来尝试解决 Windows 缺乏与fork()
等等效项的问题。毫不奇怪,它的行为与真正的 Linux 或 Unix 环境不同。
在这种情况下,posix semaphore api 看起来像是在原生 Win32 信号量之上的一个薄包装器,它在某些事情上有微妙的不同语义。以上是关于奇怪的 POSIX 信号量行为(卡在 Linux 上的 sem_wait 上)的主要内容,如果未能解决你的问题,请参考以下文章