GNU/Linux >> Linux Esercitazione >  >> Linux

Come recupero un semaforo quando il processo che lo ha decrementato a zero va in crash?

Si scopre che non c'è un modo per recuperare in modo affidabile il semaforo. Certo, chiunque può post_sem() al semaforo indicato per far aumentare di nuovo il conteggio oltre lo zero, ma come sapere quando è necessario un tale recupero? L'API fornita è troppo limitata e non indica in alcun modo quando ciò è avvenuto.

Attenzione anche agli strumenti ipc disponibili -- gli strumenti comuni ipcmk , ipcrm e ipcs sono solo per i semafori SysV obsoleti. In particolare non funzionano con i nuovi semafori POSIX.

Ma sembra che ci siano altre cose che possono essere utilizzate per bloccare le cose, che il sistema operativo rilascia automaticamente quando un'applicazione muore in un modo che non può essere catturato in un gestore di segnale. Due esempi:un socket in ascolto associato a una porta particolare o un blocco su un file specifico.

Ho deciso che il blocco su un file è la soluzione di cui avevo bisogno. Quindi, invece di un sem_wait() e sem_post() call, sto usando:

lockf( fd, F_LOCK, 0 )

e

lockf( fd, F_ULOCK, 0 )

Quando l'applicazione esce in qualsiasi modo, il file viene chiuso automaticamente, rilasciando anche il blocco del file. Altre app client in attesa del "semaforo" sono quindi libere di procedere come previsto.

Grazie per l'aiuto, ragazzi.


Usa un file di blocco invece di un semaforo, proprio come la soluzione di @ Stéphane ma senza le chiamate flock(). Puoi semplicemente aprire il file usando un lucchetto esclusivo:

//call to open() will block until it can obtain an exclusive lock on the file.
errno = 0;
int fd = open("/tmp/.lockfile", 
    O_CREAT | //create the file if it's not present.
    O_WRONLY | //only need write access for the internal locking semantics.
    O_EXLOCK, //use an exclusive lock when opening the file.
    S_IRUSR | S_IWUSR); //permissions on the file, 600 here.

if (fd == -1) {
    perror("open() failed");
    exit(EXIT_FAILURE);
}

printf("Entered critical section.\n);
//Do "critical" stuff here.

//exit the critical section
errno = 0;
if (close(fd) == -1) {
    perror("close() failed");
    exit(EXIT_FAILURE);
}

printf("Exited critical section.\n");

Questo è un problema tipico quando si gestiscono i semafori. Alcuni programmi utilizzano un unico processo per gestire l'inizializzazione/cancellazione del semaforo. Di solito questo processo fa solo questo e nient'altro. Le altre applicazioni possono attendere finché il semaforo non è disponibile. L'ho visto fare con l'API di tipo SYSV, ma non con POSIX. Simile a 'Duck ' menzionato, usando il flag SEM_UNDO nella tua chiamata semop().


Ma, con le informazioni che hai fornito ti suggerirei di non usare i semafori. Soprattutto se il tuo processo è in pericolo di essere ucciso o andare in crash. Prova a usare qualcosa che il sistema operativo pulirà automaticamente per te.


Linux
  1. Come faccio a scoprire quale processo ha un blocco su un file in Linux?

  2. Come aggiungere l'output a un file?

  3. Come reindirizzare l'output di system() su un file?

  4. Come faccio a eseguire il fork di un processo che non muore quando la shell esce?

  5. Come recuperare il file cancellato se è ancora aperto da qualche processo?

Come trovare il pacchetto che fornisce un file specifico in Linux

Nuovo processo genitore quando il processo genitore muore?

Come aggiungere una nuova riga alla fine di un file?

Come uccidere il processo che tiene il blocco Apt?

Come trovare il processo con il numero massimo di descrittori di file?

Come eseguire un file .sh all'inizio della sessione?