Как мога да накарам няколко извиквания към sem_open да работят в C?

Изпитвам много трудности да накарам семафорите да работят на Linux базирана система в C.

Процесът на моето кандидатстване е следният:

  1. Приложението стартира
  2. Приложението се разклонява в дете/родител
  3. Всеки процес използва sem_open с общо име, за да отвори семафора.

Ако създам семафора преди разклоняването, той работи добре. Изискванията обаче ми пречат да го направя. Когато се опитам да извикам sem_open за втори път, получавам грешка „Разрешението е отказано“ (чрез errno).

Възможно ли е да стане това по някакъв начин? Или има някакъв начин да отворите семафора в един процес и да използвате механизъм за споделена памет, за да го споделите с дъщерния процес?


person Community    schedule 19.02.2010    source източник


Отговори (2)


Използвате ли версията с 4 параметъра или 2 параметъра на sem_open?

Уверете се, че използвате версията с 4 параметъра и използвайте режим, който ще позволи на други процеси да отварят семафора. Ако приемем, че всички процеси са собственост на един и същ потребител, режим 0600 (S_IRUSR | S_IWUSR) ще бъде достатъчен.

Може също да искате да проверите дали umask не маскира някое от необходимите разрешения.

person R Samuel Klatchko    schedule 19.02.2010
comment
Използвах версията с четири аргумента, но разрешенията ми бяха неправилни. Изглежда, че O_RDWR не е флагът за разрешения за използване, въпреки че се показва във всеки пример, който успях да намеря. Много благодаря. - person ; 19.02.2010

Не забравяйте да посочите параметъра за режим и стойност, когато използвате O_CREAT във флаговете. Ето един работещ пример:

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

static void parent(void)
{
    sem_t * sem_id;
    sem_id=sem_open("mysem", O_CREAT, 0600, 0);
    if(sem_id == SEM_FAILED) {
        perror("parent sem_open");
        return;
    }
    printf("waiting for child\n");
    if(sem_wait(sem_id) < 0) {
        perror("sem_wait");
    }
}

static void child(void)
{
    sem_t * sem_id;
    sem_id=sem_open("mysem", O_CREAT, 0600, 0);
    if(sem_id == SEM_FAILED) {
        perror("child sem_open");
        return;
    }
    printf("Posting for parent\n");
    if(sem_post(sem_id) < 0) {
        perror("sem_post");
    }
}

int main(int argc, char *argv[])
{
    pid_t pid;
    pid=fork();
    if(pid < 0) {
        perror("fork");
        exit(EXIT_FAILURE);
    }

    if(!pid) {
        child();    
    } else {
        int status;
        parent();
        wait(&status);
    }
    return 0;
}
person shodanex    schedule 19.02.2010