2010-02-19 15 views
7

que estoy experimentando muchas dificultades para conseguir semáforos para trabajar en un sistema basado en Linux en C.¿Cómo puedo obtener múltiples llamadas a sem_open trabajando en C?

El proceso de mi solicitud es tal:

  1. aplicación se inicia
  2. horquillas de aplicación en los niños/padre
  3. Cada proceso usa sem_open con un nombre común para abrir el semáforo.

Si creo el semáforo antes de bifurcar, funciona bien. Sin embargo, los requisitos me impiden hacerlo. Cuando intento llamar al sem_open por segunda vez, aparece el error "Permiso denegado" (a través del errno).

¿Es posible hacer esto de alguna manera? ¿O hay alguna forma de abrir el semáforo en un proceso y utilizar un mecanismo de memoria compartida para compartirlo con el proceso secundario?

Respuesta

7

¿Está utilizando la versión de 4 parámetros o 2 parámetros de sem_open?

Asegúrese de utilizar la versión de 4 parámetros y utilice un modo que permita que otros procesos abran el semáforo. Suponiendo que todos los procesos son propiedad del mismo usuario, un modo de 0600 (S_IRUSR | S_IWUSR) será suficiente.

Es posible que también desee verificar que umask no esté enmascarando ninguno de los permisos necesarios.

+0

Estaba usando la versión de cuatro argumentos, pero mis permisos eran incorrectos. Parece que 'O_RDWR' no es el indicador de permisos para usar, a pesar de aparecer en todos los ejemplos que pude encontrar. Muchas gracias. –

7

No olvide especificar el modo y el parámetro de valor al usar O_CREAT en los indicadores. Aquí hay un ejemplo de trabajo:

#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; 
} 
Cuestiones relacionadas