[英]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.