C++
Tipi atomici
Ricerca…
Sintassi
- std :: atomica <T>
- std :: atomic_flag
Osservazioni
std::atomic
consente l'accesso atomico a un tipo TriviallyCopyable, dipende dall'implementazione se questo viene eseguito tramite operazioni atomiche o utilizzando i lock. L'unico tipo atomico senza blocco garantito è std::atomic_flag
.
Accesso multi-thread
Un tipo atomico può essere utilizzato per leggere e scrivere in modo sicuro in una posizione di memoria condivisa tra due thread.
Un cattivo esempio che potrebbe causare una corsa di dati:
#include <thread>
#include <iostream>
//function will add all values including and between 'a' and 'b' to 'result'
void add(int a, int b, int * result) {
for (int i = a; i <= b; i++) {
*result += i;
}
}
int main() {
//a primitive data type has no thread safety
int shared = 0;
//create a thread that may run parallel to the 'main' thread
//the thread will run the function 'add' defined above with paramters a = 1, b = 100, result = &shared
//analogous to 'add(1,100, &shared);'
std::thread addingThread(add, 1, 100, &shared);
//attempt to print the value of 'shared' to console
//main will keep repeating this until the addingThread becomes joinable
while (!addingThread.joinable()) {
//this may cause undefined behavior or print a corrupted value
//if the addingThread tries to write to 'shared' while the main thread is reading it
std::cout << shared << std::endl;
}
//rejoin the thread at the end of execution for cleaning purposes
addingThread.join();
return 0;
}
L'esempio sopra può causare una lettura corrotta e può portare a un comportamento non definito.
Un esempio di sicurezza del thread:
#include <atomic>
#include <thread>
#include <iostream>
//function will add all values including and between 'a' and 'b' to 'result'
void add(int a, int b, std::atomic<int> * result) {
for (int i = a; i <= b; i++) {
//atomically add 'i' to result
result->fetch_add(i);
}
}
int main() {
//atomic template used to store non-atomic objects
std::atomic<int> shared = 0;
//create a thread that may run parallel to the 'main' thread
//the thread will run the function 'add' defined above with paramters a = 1, b = 100, result = &shared
//analogous to 'add(1,100, &shared);'
std::thread addingThread(add, 1, 10000, &shared);
//print the value of 'shared' to console
//main will keep repeating this until the addingThread becomes joinable
while (!addingThread.joinable()) {
//safe way to read the value of shared atomically for thread safe read
std::cout << shared.load() << std::endl;
}
//rejoin the thread at the end of execution for cleaning purposes
addingThread.join();
return 0;
}
L'esempio sopra è sicuro perché tutte le operazioni store()
e load()
del tipo di dati atomic
proteggono l' int
incapsulato dall'accesso simultaneo.
Modified text is an extract of the original Stack Overflow Documentation
Autorizzato sotto CC BY-SA 3.0
Non affiliato con Stack Overflow