Domanda

Ho bisogno di sapere come evitare una condizione di competizione durante la manipolazione di segnali in C. Ogni volta che il mio programma riceve un segnale, lo voglio per alterare una lista collegata (globale). È di vitale importanza che non manca un segnale, e altrettanto importante che la lista collegata globale sto modificando non modificarle mentre il gestore è in esecuzione.

Il problema è che, se ricevo un segnale, e avviare il gestore, ma sto poi interrotto da un altro segnale. Questa (se ho capito bene) innesca una nuova esecuzione del gestore di segnale, che opererà sullo stesso set di dati globale - Inammissibilità

Non è possibile utilizzare un blocco, perché se la prima chiamata del gestore viene interrotto, sarà naturalmente mai liberare il blocco per il gestore interrompere per pick up. Così, come posso fare? Qualche idea?

È stato utile?

Soluzione

Se avete la fortuna di lavorare in un ambiente multi-threaded, uno dei modi migliori è quello di avere la lista collegata globale controllata esclusivamente da un thread separato. Interrupt sarebbero accodare le richieste a questa discussione (cosa che dovrebbe essere eseguito molto rapidamente, per esempio, semplicemente passando un puntatore), e poi il filo sarebbero procedurale passare attraverso ogni richiesta e modificare la lista collegata. Questo permette l'esecuzione lockless.

Naturalmente, si può contare solo su message passing spazzatura del vostro sistema operativo, in modo che non può essere un'opzione.

Altri suggerimenti

Si può mascherare i segnali durante l'esecuzione di gestore di segnale -. Controllo campo sa_mask di struct sigaction si passa alla sigaction() syscall

http://users.evtek.fi/~tk/rtp /signals-programming.html :

Il modo per garantire non corse a tutti, è quello di lasciare che il sistema impostato il segnale di mascheramento per noi prima di chiamare il gestore di segnale. Questo può essere fatto se si usa la chiamata di sistema sigaction () per definire sia la funzione di gestore di segnale e la maschera segnale da utilizzare quando viene eseguito il gestore. Si sarebbe probabilmente in grado di leggere la pagina di manuale per sigaction () sul proprio, ora che si ha familiarità con i vari concetti di gestione del segnale. Su vecchi sistemi, tuttavia, non troverete questa chiamata di sistema, ma è ancora potrebbe trovare la chiamata sigvec (), che consente una funzionalità simile.

Credo che si dovrebbe Seriate il signal.just come la coda di lavoro Per esempio. tutto il segnale dovrebbe mettere in una coda di lavoro (FIFO), e poi il sondaggio thread in esecuzione la coda per tutto il tempo. se la coda non è vuota, questa discussione sarà raccogliere il segnale alto e iniziare `s handler. continuare a fare così, fino a quando la coda è vuota.

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top