Domanda

C'è un modo per fare una funzione atomica in C.

Io non sono alla ricerca di una soluzione portatile (piattaforme alla ricerca di - Win, Linux).

È stato utile?

Soluzione

Forse.

Dipende interamente dalla vostra definizione di "atomica".

  • In un singolo core, profondamente infisso ambiente senza sistema operativo coinvolto solito si può attivare e disattivare gli interrupt. Questo può essere utilizzato per consentire una funzione di essere atomica contro codice di gestore di interrupt. Ma se si dispone di un bus multi-master, un motore DMA, o qualche altro dispositivo hardware in grado di scrivere la memoria in modo indipendente, quindi gli interrupt anche mascheramento potrebbe non fornire una solida garanzia sufficiente in alcune circostanze.

  • In un RTOS (sistema operativo in tempo reale) ambiente, il kernel del sistema operativo di solito fornisce primitive basso livello di sincronizzazione come sezioni critiche. Una sezione critica è un blocco di codice che si comporta "essenzialmente" atomicamente, almeno rispetto a tutte le altre sezioni critiche. Di solito è fondamentale per l'implementazione del sistema operativo di altre primitive di sincronizzazione.

  • In un ambiente multi-core, un basso livello primitivo chiamato uno spinlock è spesso disponibile. Viene utilizzato per evitare ingresso ad un blocco di codice che deve essere atomico rispetto ad altri utenti dello stesso oggetto spinlock, e funziona bloccando core CPU attesa in un loop stretto finché viene rilasciato il blocco (da qui il nome).

  • In molti ambienti di threading, primitive più complessi come eventi, semafori, mutex, e le code sono forniti dal framework filettatura. Questi cooperano con lo scheduler filo tale che le discussioni in attesa che accada qualcosa non eseguire affatto finché la condizione è soddisfatta. Questi possono essere usati per effettuare azioni di una funzione atomico rispetto ad altri thread condividono lo stesso oggetto di sincronizzazione.

Una regola generale sarebbe quello di utilizzare le funzionalità di più alto livello disponibili nel proprio ambiente che sono adatti al compito. Nel migliore dei casi, un thread oggetto di sicurezza esistenti, come una coda di messaggi può essere utilizzato per evitare di dover fare nulla di speciale nel codice a tutti.

Altri suggerimenti

Se si vuole fare in modo la funzione non sarà interrotto dal segnale, utilizzare sigprocmask() per mascherare e smascherare i segnali, anche se alcuni segnali non possono essere bloccati (come SIGKILL) e il comportamento per bloccare alcuni segnali (come SIGSEGV) non è definito.

Vedere man sigprocmask per i dettagli.

Non portabile, almeno. Per alcuni sistemi, probabilmente si può avvicinarlo, facendo le cose come girare di interrupt della macchina, per evitare che il kernel da pregiudicare la vostra funzione. Ma sarà molto difficile, soprattutto per i sistemi non-embedded.

Avrete bisogno di supporto specifico per la piattaforma per farlo - sia attraverso l'uso di speciali intrinseci compilatore per le istruzioni di hardware, oppure utilizzando il supporto del sistema operativo. Né C nè C ++ ha standardizzato roba sincronizzazione.

Definire che cosa si intende per 'atomica.' Vuoi dire 'atomica', nel senso che nessun altro processo o thread saranno selezionati per la pianificazione quando si esegue la funzione? O vuoi dire che gli eventuali oggetti condivisi fa riferimento nella vostra funzione non saranno modificati con qualsiasi altro thread, mentre la funzione viene eseguito?

Nel primo caso, non si può davvero controllare che dal userspace. Se siete su una macchina singola CPU puoi eventualmente garanzia atomicità alzando la priorità del processo per la massima priorità possibile (da userspace). Ma anche in questo caso non è garantito perché il vostro algoritmo di scheduling può ancora permettere un altro processo per l'esecuzione. L'unico modo affidabile per farlo è dal sistema operativo. Per una macchina singola CPU che ci si disabilitare gli interrupt. Per una macchina multi-core avresti bisogno di bloccare il bus e attendere che tutti i processi in esecuzione su altre CPU per essere tolto.

La domanda qui è: Perché si vuole garantire atomicità In generale, il requisito che solo il vostro processo può essere in esecuzione e non altri, non dovrebbe esistere in userspace. Se si vuole fare in modo determinate strutture di dati sono accessibili solo da un thread alla volta, quindi si dovrebbe utilizzare una libreria portabile filo (come pthread per esempio), e recintare la funzione come una sezione critica.

Se per atomic intendi 'solo un thread alla volta', allora si può solo proteggere la funzione con un blocco di sezione critica (in Windows). In Linux, io uso un blocco mutex / sbloccare al più o meno emulare una sezione critica.

Si potrebbe voler esaminare i semafori POSIX, mutex o simili, che potrebbe funzionare sia su Windows e Linux.

Uso esempio cygwin o MinGW è ancora possibile scrivere codice portabile tra Linux e Windows.

Ancora meglio è possibile creare librerie di Windows su Linux: http : //cdtdoug.blogspot.com/2009/05/mingw-cross-for-linux.html

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