C++
Types atomiques
Recherche…
Syntaxe
- std :: atomique <T>
- std :: atomic_flag
Remarques
std::atomic
permet l'accès atomique à un type TriviallyCopyable, il dépend de l'implémentation si cela se fait via des opérations atomiques ou en utilisant des verrous. Le seul type atomique garanti sans verrou est std::atomic_flag
.
Accès multithread
Un type atomique peut être utilisé pour lire et écrire en toute sécurité dans un emplacement de mémoire partagé entre deux threads.
Un mauvais exemple susceptible de provoquer une course de données:
#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'exemple ci-dessus peut provoquer une lecture corrompue et entraîner un comportement indéfini.
Un exemple avec la sécurité des threads:
#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'exemple ci - dessus est sûr parce que tout store()
et load()
opérations du atomic
type de données protègent le encapsulé int
d' un accès simultané.
Modified text is an extract of the original Stack Overflow Documentation
Sous licence CC BY-SA 3.0
Non affilié à Stack Overflow