尝试使用信号量创建一个简单的程序

时间:2014-12-08 06:47:09

标签: c unix semaphore

我正在尝试创建一个程序,该程序会分析睡眠几秒钟的子进程,然后释放正在等待的父进程的信号量。我花了几天时间阅读信号量和在线研究,但这一切都让人非常困惑。此外,每个示例都是大量代码,看起来很简单,每个代码都完全不同。

编辑:DERP!所以,代码不起作用。孩子的分叉很好,但是父母永远被困在sem_wait上。因此,我实现信号量的方式似乎有问题。

这是我到目前为止所拥有的:

#include <semaphore.h>
#include <stdio.h>
#include <stdlib.h>

int main(int argc, char *argv[])
{
    int j, dummy, intCast;
    sem_t s;

    if (argc < 2 || strcmp(argv[1], "--help") == 0){
        printf("Usage: sem_sync X (X is one or more ints)");
        exit(EXIT_FAILURE);
    }

    setbuf(stdout, NULL); /* Make stdout unbuffered, since we
                                           terminate child with _exit() */
    printf(" Parent started\n");

    sem_init(&s, 0, 0);
    for (j = 1; j < argc; j++) {
        switch (fork()) {
        case -1:
            printf("Error on fork %d", j);
            exit(EXIT_FAILURE);

        case 0: /* Child */
            intCast = atoi(argv[j]); // Casts the argument into an integer
            printf("Child sleeping for %d seconds\n",intCast);
            sleep(intCast);
            sem_post(&s);
            _exit(EXIT_SUCCESS);

        default: /* Parent loops to create next child */
            break;
        }
    }
    printf(" Parent is waiting\n");
    sem_wait(&s);
    printf(" Parent ready to go\n");
    exit(EXIT_SUCCESS);
}

这是使用sem_open()和sem_close()

的工作代码
int main(int argc, char *argv[])
{
    int j, intCast;
    sem_t *s;

    printf(" Parent started\n");
    s = sem_open("file1", O_CREAT, 0600, 0);
    if (s == SEM_FAILED){
        printf("sem_open() failed. errno:\n");
    }

    for (j = 1; j < argc; j++) {
        switch (fork()) {
        case -1:
            printf("Error on fork %d", j);
            exit(EXIT_FAILURE);
        case 0: /* Child */
            intCast = atoi(argv[j]);
            printf("Child sleeping for %d seconds\n",intCast);
            sleep(intCast);
            sem_post(s);
            _exit(EXIT_SUCCESS);
        default: 
            break;
        }
    }
    printf(" Parent is waiting\n");
    for (j = 1; j < argc; j++){
        sem_wait(s);
    }
    sem_close(s);
    exit(EXIT_SUCCESS);
}

1 个答案:

答案 0 :(得分:1)

使用sem_open()代替sem_init()。使用sem_init()创建的信号量不会在进程间共享,除非您在共享内存中创建它们。将sem_open()用于您想要做的事情要容易得多。

修改:请记住,sem_open()会创建一个您需要使用sem_unlink()删除的持久信号量。如果前一次调用可能存在杂散文件,您可能希望在打开文件之前取消链接,如下所示:

sem_unlink(filename);
sem_open(filename, O_CREAT, etc...);

以便在打开之前删除命名的信号量。否则,如果它已经存在,sem_open将打开现有的信号量并继承信号量中已有的任何计数。