2010-02-19 4 views
7

Я испытываю много трудностей получать семафоры работать на системе, основанной на Linux в C.Как я могу получить несколько вызовов sem_open, работающих в C?

Процесс моего приложения таково:

  1. Применения начинается
  2. вилки Применения в ребенок/parent
  3. Каждый процесс использует sem_open с общим именем для открытия семафора.

Если я создаю семафор перед разветвлением, он отлично работает. Однако требования не позволяют мне это делать. Когда я пытаюсь позвонить sem_open во второй раз, я получаю ошибку «Разрешение отказа» (через errno).

Можно ли это сделать каким-либо образом? Или есть способ открыть семафор в одном процессе и использовать механизм общей памяти, чтобы поделиться им с дочерним процессом?

ответ

7

Используете ли вы параметр параметра или параметр параметра sem_open 4 или 2?

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

Возможно, вы также захотите проверить, что вы umask не маскируете какие-либо необходимые разрешения.

+0

Я использовал версию с четырьмя аргументами, но мои права были неправильными. Похоже, что 'O_RDWR' не является флажком разрешений для использования, несмотря на то, что он отображается в каждом примере, который я мог найти. Огромное спасибо. – 2010-02-19 14:51:35

7

Не забудьте указать параметр режима и значения при использовании 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; 
}