簡體   English   中英

C ++中的多線程數據同步

[英]Multithread data synchronisation in C++

這是我的問題。 我有幾個線程可以修改結構的屬性,還有一個線程可以讀取結構。 如何確定正在讀取的值沒有被其他線程更改? 就我而言,屬性只能由一個線程修改。

例:

typedef struct
{
    int a;
    double b;

} data;

data glob;

int main()
{

    thread reader([]()
    {
        while(1)
        {
            sleep(1s);
            cout << glob;
        }
    });

    thread writer1([]()
    { 
        while(1)
            glob.a++;
    });
    thread writer2([]()
    { 
        while(1)
            glob.b++;
    });


    int i;
    cin >>i;
}

然后,如何確定當我讀取glob時,writer1和writer2沒有對其進行修改?

#include <thread>
#include <atomic>
#include <iostream>
#include<chrono>

typedef struct
{
    std::atomic_int a;
    std::atomic<double> b;



} data;



data glob;


int main()
{
    glob.a.store(0);//store data in the atomic variable
    glob.b.store(0.0);

    std::thread reader([]()
    {
        while (1)
        {
            std::this_thread::sleep_for(std::chrono::seconds(1));
            std::cout << glob.a.load() << " " << glob.b.load() << std::endl; //get the value of the variable
        }
    });

    std::thread writer1([]()
    {
        while (1)
            glob.a++;
    });
    std::thread writer2([]()
    {
        while (1)
            glob.b.store(glob.b.load() +1); // std::atomic<double> has no member operator++ so have to improvise
    });


    int i;
    std::cin >> i;
}

這是使用<atomic>進行不可分割的訪問和寫入操作的問題的簡單可行解決方案。

使用互斥鎖后,就很簡單了。

http://en.cppreference.com/w/cpp/thread/mutex

http://en.cppreference.com/w/cpp/thread/lock_guard

代碼示例: 未經測試可能會導致數據爭用和/或死鎖

#include <thread>
#inclue <mutex>
typedef struct
{
    int a;
    double b;

} data;

data glob;
mutex mymutex;

int main()
{

    thread reader([]()
    {
        while(1)
        {
            mymutex.lock();
            sleep(1s);
            cout << glob;
            mymutex.unlock();
        }
    });

    thread writer1([]()
    { 
        while(1)
            mymutex.lock();
            glob.a++;
            mymutex.unlock();
    });
    thread writer2([]()
    { 
        while(1)
            mymutex.lock();
            glob.b++;
            mymutex.unlock();
    });


    int i;
    cin >>i;
}

因此這將在更改glob時鎖定互斥鎖,並在完成更改后將其解鎖。 互斥鎖被鎖定后,另一個試圖訪問該互斥鎖的線程將無法訪問,因此將稍等片刻,然后重試。 最終它將捕獲並能夠將其自身鎖定。 然后另一個線程將不得不等待它解鎖。

我鏈接的lock_guard是使用互斥鎖的一種更安全的方法,但僅適用於函數。 您將其放在函數的開頭,然后它將保持鎖定狀態,直到函數返回為止。 這意味着您不必確保在函數的每個返回路徑上都解鎖互斥鎖,因為這是自動完成的。

互斥鎖確實存在死鎖問題。 當您鎖定互斥鎖,然后在互斥鎖解鎖之前嘗試在同一線程中再次鎖定互斥鎖時,會發生這種情況。 然后它將永遠等待無法解鎖,其他線程也無法繼續。 如果要從互斥區域調用函數,則簡單的解決方案是使用多個互斥體。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM