2009-04-01 12 views

risposta

14

Forse.

Dipende interamente dalla definizione di "atomico".

  • In un singolo core, profondamente incorporato ambiente senza sistema operativo coinvolto solito si può attivare e disattivare gli interrupt. Questo può essere usato per consentire a una funzione di essere atomica rispetto al codice del gestore di interrupt. Ma se si dispone di un bus multi-master, un motore DMA o qualche altro dispositivo hardware in grado di scrivere memoria indipendentemente, anche in alcuni casi la mascheratura degli interrupt potrebbe non fornire una garanzia sufficiente.

  • In un ambiente RTOS (sistema operativo in tempo reale), il kernel del sistema operativo in genere fornisce primitive di sincronizzazione di basso livello come le 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 SO di altre primitive di sincronizzazione.

  • In un ambiente multi-core, è spesso disponibile una primitiva di basso livello denominata spinlock. Viene usato per evitare l'ingresso in un blocco di codice che deve essere atomico rispetto ad altri utenti dello stesso oggetto spinlock, e opera bloccando il core della CPU in attesa in un circuito chiuso finché il blocco non viene rilasciato (da cui il nome).

  • In molti ambienti di threading, le strutture più complesse come eventi, semafori, mutex e code sono fornite dal framework di threading. Questi cooperano con lo schedulatore di thread in modo tale che i thread in attesa che qualcosa accada non vengono eseguiti affatto fino a quando la condizione non viene soddisfatta. Questi possono essere utilizzati per rendere atomiche le azioni di una funzione rispetto ad altri thread che condividono lo stesso oggetto di sincronizzazione.

Una regola generale sarebbe utilizzare le funzionalità di livello più alto disponibili nel proprio ambiente che siano adatte all'attività. Nel migliore dei casi, è possibile utilizzare un oggetto thread-safe esistente come una coda di messaggi per evitare di dover fare qualcosa di speciale nel codice.

1

Non portabile, almeno. Per alcuni sistemi, è probabile che ci si avvicini, facendo cose come l'interruzione degli interrupt della macchina, per impedire al kernel di anticipare la propria funzione. Ma sarà molto difficile, specialmente per i sistemi non integrati.

3

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) è indefinito .

Vedere man sigprocmask per dettagli.

1

Avrete bisogno di un supporto specifico per piattaforma per farlo - sia attraverso l'uso di speciali intrinseche del compilatore per le istruzioni hardware, sia utilizzando il supporto del sistema operativo. Né C né C++ hanno elementi di sincronizzazione standardizzati.

1

Definisci cosa intendi per "atomico". Intendi "atomico" nel senso che nessun altro processo o thread sarà selezionato per la pianificazione quando si esegue la funzione?O vuoi dire che qualsiasi oggetto condiviso referenziato nella tua funzione non verrà modificato da nessun altro thread mentre la tua funzione è in esecuzione?

Per il primo, non è possibile controllarlo dallo spazio utente. Se si utilizza una macchina con una singola CPU, è possibile garantire l'atomicità di aumentando la priorità del processo con la massima priorità possibile (dallo spazio utente). Ma anche in questo caso non è garantito perché l'algoritmo di pianificazione può ancora consentire l'esecuzione di un altro processo. L'unico modo affidabile per farlo è dal sistema operativo. Per una macchina con una singola CPU disabiliterai gli interrupt. Per un computer multi-core è necessario bloccare il bus e attendere che tutti i processi in esecuzione su altre CPU vengano rimossi.

La domanda è: perché vuoi garantire l'atomicità? In generale, il requisito che solo il tuo processo possa essere in esecuzione e non altri, non dovrebbe esistere nello spazio utente. Se vuoi assicurarti che alcune strutture dati siano accessibili solo da un thread alla volta, allora dovresti usare una libreria di thread portatile (come ad esempio pthread) e recidere la tua funzione come una sezione critica.

1

Se per atomico si intende "solo un thread alla volta", è possibile semplicemente proteggere la funzione con un blocco di sezione critica (in Windows). In Linux, utilizzo un blocco/sblocco mutex per emulare più o meno una sezione critica.

0

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

Utilizzo ad es. cygwin o minGW è persino possibile scrivere codice portatile tra Linux e Windows.

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