C - 带信号量的多个 fork

标签 c fork semaphore critical-section

我试图最终解决生产者-消费者问题,但我首先需要能够使用信号量创建关键部分。我目前遇到的问题是,当我运行程序时,临界区有时有多个进程会进入它。我希望在给定时间只有一个进程位于关键部分。这是我目前拥有的代码:

#include <stdio.h>
#include <stdlib.h>
#include <errno.h>
#include <sys/types.h>
#include <sys/ipc.h>
#include <sys/sem.h>

#define MAX 20

int main(void)
{
    key_t key = 1114;
    int semid, count,
        mutex = 0;


    //Initialize Semaphore Buffers
    struct sembuf oper0;

    pid_t waitId;
    pid_t parentId = getpid();

    //Create processes
    for(count = 0; count < MAX; count++)
    {
        if((waitId = fork()) == 0)
        {
            break;
        }
    }

    //Create a semaphore set of 3; I will be adding more semaphores
    if ((semid = semget(key, 3, 0600 | IPC_CREAT)) == -1) {
        printf("error in semget");
        exit(1);
    }

    // BINARY/MUTEX - initialize semaphore0 to 1 
    if(semctl(semid, mutex, SETVAL, 1) == -1)
    {
        printf("error in semctl");
        exit(0);
    }

    //Decrement semaphore 0
    oper0.sem_op = -1;
    oper0.sem_flg = 0;
    if (semop(semid, &oper0, 1) == -1) {
        printf("error decrementing semaphore \n");
        exit(1);
    }

    printf(" -- CRITICAL SECTION START ----------- \n\n");
    printf("%5d    %d     %s\n", getpid(), semctl(semid, 0, GETVAL, oper0.sem_num), " -- Semaphore 0");
    printf(" -- CRITICAL SECTION END -- \n\n");    

    //Increments semaphore 0
    oper0.sem_op = 1;
    oper0.sem_flg = 0;
    if (semop(semid, &oper0, 1) == -1) {
        printf("error incrementing semaphore \n");
        exit(1);
    }

    int i;
    if(getpid() == parentId)
    {
        for(i = 0; i < MAX i++)
        {
            wait(&waitId);
        }
    }
    else
    {
        exit(waitId);
    }

    // Remove semaphore 
    if (semctl(semid, 0, IPC_RMID) == -1) {
        printf("error in semctl");
        exit(1);
    }

    return 0;
}

这是一个示例输出:

 -- CRITICAL SECTION START ----------- 

 1097    0      -- Semaphore 0
 -- CRITICAL SECTION END -- 

 -- CRITICAL SECTION START ----------- 

 1085    0      -- Semaphore 0
 -- CRITICAL SECTION END -- 

 -- CRITICAL SECTION START ----------- 

 -- CRITICAL SECTION START ----------- 

 1095    0      -- Semaphore 0
 -- CRITICAL SECTION END -- 

 1093    0      -- Semaphore 0
 -- CRITICAL SECTION END -- 

 -- CRITICAL SECTION START ----------- 

 -- CRITICAL SECTION START ----------- 

 1087    0      -- Semaphore 0
 -- CRITICAL SECTION END -- 

 1089    0      -- Semaphore 0
 -- CRITICAL SECTION END -- 

 -- CRITICAL SECTION START ----------- 

 1091    0      -- Semaphore 0
 -- CRITICAL SECTION END -- 

为什么信号量有时会锁定一个进程,而有时又会允许两个进程进入?

最佳答案

因为你在每个子进程中执行semctl(semid, mutex, SETVAL, 1)。您真的只想这样做一次。如果将 fork 循环移到创建和初始化信号量的位置之后,您可能会发现它看起来好多了。

此外,您可能想在 printf 之后执行 fflush(stdout);如果 stdout 被缓冲,那么即使缓冲区被写入关键部分,输出最终仍可能会混合在一起。

关于C - 带信号量的多个 fork ,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/12701322/

相关文章:

java - 二进制信号量与可重入锁

c - 获取 "warning:assignment from incompatible pointer type"

奇怪的数组覆盖

java - 我怎样才能实现返回多次重复的颜色的方法?图像具有的所有 RGB 值

objective-c - 匿名与定义枚举

后跟 exec 时的克隆、 fork 、vfork 行为

c - pipe() 数据未传输到子进程

fork - 控制 fork 进程的名称

c - 信号量似乎无法在多线程中正常工作

c - 尝试学习如何在受控循环中用 C 实现信号量