Zoeken…


Syntaxis

  • std :: atomaire <T>
  • std :: atomic_flag

Opmerkingen

std::atomic geeft atomaire toegang tot een TriviallyCopyable-type, het is implementatie-afhankelijk als dit wordt gedaan via atomaire bewerkingen of met behulp van sloten. Het enige gegarandeerde lock-free std::atomic_flag is std::atomic_flag .

Toegang met meerdere threads

Een atoomtype kan worden gebruikt om veilig te lezen en te schrijven naar een geheugenlocatie die wordt gedeeld tussen twee threads.

Een slecht voorbeeld dat waarschijnlijk een gegevensrace veroorzaakt:

#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;
}

Het bovenstaande voorbeeld kan een beschadigde uitlezing veroorzaken en kan leiden tot ongedefinieerd gedrag.

Een voorbeeld met draadveiligheid:

#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;
}

Het bovenstaande voorbeeld is veilig omdat alle store() en load() bewerkingen van het atomic gegevenstype de ingekapselde int beschermen tegen gelijktijdige toegang.



Modified text is an extract of the original Stack Overflow Documentation
Licentie onder CC BY-SA 3.0
Niet aangesloten bij Stack Overflow