POSIX 子进程和父进程之间的信号量

POSIX semaphores between child and parent processes

我正在尝试学习信号量以及它们如何在进程之间工作,因此我想创建一个程序,从两个单独的 for() 循环中打印字符串 "abcd" 的 10 倍。一个 for() 包含 "ab" 字符串,而另一个包含 "cd" 字符串。我认为代码很好,但显然不是。如果您能指出任何错误或我有什么误解,我将不胜感激。

代码如下:

int main(void)
{

int i;
char *p;
sem_t *sem; //First semaphore
sem_t *sem2; //Second semaphore

//create, initialize semaphores
sem = sem_open("/semaphore1", O_CREAT,  0644, 1);
sem2 = sem_open("/semaphore2", O_CREAT,  0644, 1);

if (fork()) //Child process
{
     for (i=0;i<10;i++)
     {
        sem_wait(sem2); //Lock the semaphore
        for (p="ab"; *p; p++)
        {
            write(1, p, 1);
            usleep(100);
        }
        sem_post(sem); //Release the semaphore lock
     }
     wait(NULL);
}
else //Parent process
{
     for (i=0;i<10;i++)
     {
        sem_wait(sem); //Lock the semaphore
        for (p="cd\n"; *p; p++)
        {
            write(1, p, 1);
            usleep(100);
        }
        sem_post(sem2); //Release the semaphore lock
     }
}

//Close the Semaphores
sem_close(sem);
sem_unlink("/semaphore1");
sem_close(sem2);
sem_unlink("/semaphore2");
return 0;
}

以及输出之一:

abcd
cadb
cadb
cadb
cabd
cabd
cabd
cadb
cabd
cadb

如评论中所述,您需要将第一个信号量(在下面的代码中重命名为 sem1 以与 sem2 对称)初始化为 0 而不是 1 以便父进程先行。

子进程和父进程注释放错了地方(父进程从 fork() 得到非零结果,因此在 if 中工作)。即使没有对 usleep() 的任何调用,此版本也会产生所需的输出。名义上,只有一个进程需要使用 sem_close()sem_unlink(),但由于您不检查或报告任何错误,因此您不会注意到失败的调用。

#include <stdio.h>
#include <semaphore.h>
#include <unistd.h>
#include <sys/wait.h>

int main(void)
{
    int i;
    char *p;
    sem_t *sem1; // First semaphore
    sem_t *sem2; // Second semaphore

    // create, initialize semaphores
    sem1 = sem_open("/semaphore1", O_CREAT,  0644, 0);
    sem2 = sem_open("/semaphore2", O_CREAT,  0644, 1);

    if (fork()) // Parent process
    {
        for (i = 0; i < 10; i++)
        {
            sem_wait(sem2); // Lock the semaphore
            for (p = "ab"; *p; p++)
            {
                write(1, p, 1);
                //usleep(100);
            }
            sem_post(sem1); // Release the semaphore lock
        }
        wait(NULL);
    }
    else // Child process
    {
        for (i = 0; i < 10; i++)
        {
            sem_wait(sem1); // Lock the semaphore
            for (p = "cd\n"; *p; p++)
            {
                write(1, p, 1);
                //usleep(100);
            }
            sem_post(sem2); // Release the semaphore lock
        }
    }

    // Close the Semaphores
    sem_close(sem1);
    sem_unlink("/semaphore1");
    sem_close(sem2);
    sem_unlink("/semaphore2");
    return 0;
}

示例输出:

abcd
abcd
abcd
abcd
abcd
abcd
abcd
abcd
abcd
abcd