【问题标题】:Wait for a Forked Process when using a Semaphore使用信号量时等待分叉进程
【发布时间】:2013-10-04 23:41:29
【问题描述】:

我正在尝试在C Linux 中编写一个练习,其中我有一个信号量,其中包含 2 个点和由参数输入的“n”个进程。我需要前 2 个进程使用信号量使用 2 个点,每个 5 秒,然后将信号量留给其他剩余进程来完成他们的工作。问题是并非所有其他进程都等待信号量空闲,其中一些显示信号量错误(查看底部的结果)。我相信问题在于等待子进程,因为我有一个waitipid 和一个wait 函数,但我需要如果信号量中有一个空闲点,任何运行的子进程都可以使用它。代码如下:

//gcc SemaphoreExample.c -o s
//./s 5

#include <stdio.h>
#include <stdlib.h>
#include <errno.h>
#include <string.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <unistd.h>
#include <sys/wait.h>
#include <sys/ipc.h>
#include <sys/sem.h>

void semaphoreTask(int semid, int semnum, int semBusy)
{
    struct sembuf data;
    data.sem_num = semnum;
    data.sem_flg = 0;
    data.sem_op = semBusy;

    if(semop(semid,&data,1) == -1)
    {
        printf("\nSemaphore Error\n");
        exit(-1);
    }
}

int main(int argc, char *argv[])
{
    int i, fdSemaphore, quantity, fdsemctl, j;
    pid_t pid[15];

    system("clear");

    if(argc-1 < 1)
    {
        printf("Some arguments are missing\n");
        return EXIT_FAILURE;
    }

    printf("Number of arguments entered:\n\nargc: %d\n\nValues from the arguments:\n\n",argc-1);

    for(i=0;i<argc;i++)
    {
        printf("argv[%d]: %s\n",i,argv[i]);
    }

    printf("\n\n");

    fdSemaphore = semget(1234,1,IPC_CREAT|0777);

    if(fdSemaphore == -1)
    {
        printf("\nError creating the Semaphore\n");
        return EXIT_FAILURE;
    }

    fdsemctl = semctl(fdSemaphore,0,SETVAL,2);

    if(fdsemctl == -1)
    {
        printf("\nError opening the Semaphore\n");
        return EXIT_FAILURE;
    }

    quantity = atoi(argv[1]);

    for(i=0;i<quantity;i++)
    {
        pid[i] = fork();

        if(pid[i] == -1)
        {
            printf("\nError creating the Child Process\n");
            return EXIT_FAILURE;
        }

        if(pid[i] == 0)
        {
            semaphoreTask(fdSemaphore,0,-1);
            printf("\n[%d] I go to sleep\n",getpid());
            sleep(5);
            printf("\n[%d] I wake up\n",getpid());
            semaphoreTask(fdSemaphore,0,1);
        }
        else
        {
            //printf("\nJust wait\n");
            waitpid(pid[i],NULL,WNOHANG);
        }
    }

    for(j=0;j<quantity;j++)
    {
        wait(NULL);
    }

    semctl(fdSemaphore,0,IPC_RMID);

    return EXIT_SUCCESS;
}

这是我得到的结果:

Result:

Number of arguments entered:

argc: 1

Values from the arguments:

argv[0]: ./s
argv[1]: 5


[2845] I go to sleep

[2844] I go to sleep

[2845] I wake up

[2844] I wake up

Semaphore Error

[2843] I go to sleep

Semaphore Error

Semaphore Error

[2843] I wake up

Semaphore Error

我应该只使用wait 还是waitpid

【问题讨论】:

    标签: c linux fork wait semaphore


    【解决方案1】:

    问题是信号量被分叉的孩子删除了。

    行后

    semaphoreTask(fdSemaphore,0,1);
    

    添加

    exit(0);
    

    【讨论】:

      【解决方案2】:

      如果你使用 sem_post 和 sem_wait 调用,实现你想要的会简单得多。我在一个 OpenBSD 系统上,我假设 Linux 也有同样的东西。

      【讨论】:

      • 我怀疑大多数人都同意 posix 信号量比 sysv 信号量更容易处理,但这并不是真正的答案。
      猜你喜欢
      • 2012-02-03
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2018-10-13
      • 1970-01-01
      • 1970-01-01
      • 2016-07-16
      • 2011-10-14
      相关资源
      最近更新 更多