【问题标题】:Strange POSIX semaphore behavior (stuck on sem_wait on Linux)奇怪的 POSIX 信号量行为(卡在 Linux 上的 sem_wait 上)
【发布时间】: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 上对其进行测试,并且程序按预期运行。我在这里错过了什么?

【问题讨论】:

    标签: linux posix semaphore


    【解决方案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 信号量之上的一个薄包装器,它在某些事情上有微妙的不同语义。
    猜你喜欢
    • 2018-02-06
    • 1970-01-01
    • 1970-01-01
    • 2015-12-03
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多