2010-02-19 5 views
7

che sto vivendo un sacco di difficoltà a ottenere semafori per lavorare su un sistema basato su Linux in C.Come posso ricevere più chiamate a sem_open che funzionano in C?

Il processo di mia domanda è tale:

  1. Applicazione inizia
  2. forchette applicazione in bambino/genitore
  3. Ogni processo utilizza sem_open con un nome comune per aprire il semaforo.

Se creo il semaforo prima della foratura, funziona correttamente. Tuttavia, i requisiti mi impediscono di farlo. Quando provo a chiamare lo sem_open per la seconda volta, visualizzo un errore "Autorizzazione negata" (tramite errno).

È possibile farlo in qualche modo? O c'è un modo per aprire il semaforo in un unico processo e utilizzare un meccanismo di memoria condivisa per condividerlo con il processo figlio?

risposta

7

Si sta utilizzando la versione a 4 parametri o 2 parametri di sem_open?

Assicurarsi di utilizzare la versione a 4 parametri e utilizzare una modalità che consenta ad altri processi di aprire il semaforo. Supponendo che tutti i processi siano di proprietà dello stesso utente, sarà sufficiente una modalità di 0600 (S_IRUSR | S_IWUSR).

Si consiglia inoltre di verificare che umask non stia nascondendo le autorizzazioni necessarie.

+0

Stavo usando la versione a quattro argomenti, ma le mie autorizzazioni non erano corrette. Sembra che 'O_RDWR' non sia il flag di permessi da usare, nonostante sia mostrato in ogni esempio che ho trovato. Grazie mille. –

7

Non dimenticare di specificare il parametro mode e value quando si utilizza O_CREAT nei flag. Ecco un esempio funzionante:

#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; 
} 
Problemi correlati