亚洲乱码中文字幕综合,中国熟女仑乱hd,亚洲精品乱拍国产一区二区三区,一本大道卡一卡二卡三乱码全集资源,又粗又黄又硬又爽的免费视频

C++實(shí)現(xiàn)多線程并發(fā)場(chǎng)景下的同步方法

 更新時(shí)間:2025年02月18日 10:06:14   作者:kucupung  
在C++中實(shí)現(xiàn)多線程并發(fā)場(chǎng)景下的同步方法,包括使用互斥鎖、獨(dú)占鎖、共享鎖和原子操作的實(shí)現(xiàn),具有一定的參考價(jià)值,感興趣的可以了解一下

如果在多線程程序中對(duì)全局變量的訪問(wèn)沒(méi)有進(jìn)行適當(dāng)?shù)耐娇刂疲ɡ缡褂没コ怄i、原子變量等),會(huì)導(dǎo)致多個(gè)線程同時(shí)訪問(wèn)和修改全局變量時(shí)發(fā)生競(jìng)態(tài)條件(race condition)。這種競(jìng)態(tài)條件可能會(huì)導(dǎo)致一系列不確定和嚴(yán)重的后果。

在C++中,可以通過(guò)使用互斥鎖(mutex)、原子操作、讀寫(xiě)鎖來(lái)實(shí)現(xiàn)對(duì)全局變量的互斥訪問(wèn)。

一、缺乏同步控制造成的后果

1. 數(shù)據(jù)競(jìng)爭(zhēng)(Data Race)

數(shù)據(jù)競(jìng)爭(zhēng)發(fā)生在多個(gè)線程同時(shí)訪問(wèn)同一個(gè)變量,并且至少有一個(gè)線程在寫(xiě)該變量時(shí)沒(méi)有進(jìn)行同步。由于缺少同步機(jī)制,多個(gè)線程對(duì)全局變量的操作可能會(huì)相互干擾,導(dǎo)致變量的值不可預(yù)測(cè)。

示例:

#include <iostream>
#include <thread>

int globalVar = 0;

void increment() {
    globalVar++;
}

int main() {
    std::thread t1(increment);
    std::thread t2(increment);
    t1.join();
    t2.join();

    std::cout << "Global variable: " << globalVar << std::endl;
    return 0;
}

后果:

  • 上面的代碼中,globalVar++ 并不是一個(gè)原子操作。它由多個(gè)步驟組成:讀取值、增加值、寫(xiě)回。在這段代碼中,t1 和 t2 可能會(huì)同時(shí)讀取globalVar的值,導(dǎo)致兩個(gè)線程同時(shí)修改它的值,最終的結(jié)果會(huì)小于預(yù)期的2。這就是典型的數(shù)據(jù)競(jìng)爭(zhēng)。

2. 不一致的狀態(tài)(Inconsistent State)

在沒(méi)有同步控制的情況下,多個(gè)線程可能會(huì)對(duì)全局變量進(jìn)行同時(shí)讀寫(xiě)操作,導(dǎo)致變量處于不一致的狀態(tài)。例如,多個(gè)線程可能會(huì)同時(shí)讀取和修改相同的變量,導(dǎo)致最終狀態(tài)不符合預(yù)期。

示例: 假設(shè)你有一個(gè)程序要求維護(hù)一個(gè)全局的計(jì)數(shù)器。如果沒(méi)有加鎖來(lái)確保線程安全,兩個(gè)線程同時(shí)執(zhí)行時(shí),計(jì)數(shù)器可能會(huì)被寫(xiě)成一個(gè)無(wú)意義的值。

#include <iostream>
#include <thread>

int counter = 0;

void increment() {
    for (int i = 0; i < 100000; ++i) {
        counter++;  // 非線程安全操作
    }
}

int main() {
    std::thread t1(increment);
    std::thread t2(increment);

    t1.join();
    t2.join();

    std::cout << "Counter: " << counter << std::endl;
    return 0;
}

后果:

  • 在沒(méi)有同步的情況下,counter++ 可能會(huì)導(dǎo)致多個(gè)線程在同一時(shí)刻讀取到相同的計(jì)數(shù)器值,并同時(shí)將相同的更新值寫(xiě)回變量,這會(huì)使得counter的最終值遠(yuǎn)小于預(yù)期的200000。
  • 這可能會(huì)導(dǎo)致程序的業(yè)務(wù)邏輯錯(cuò)誤,特別是如果全局變量用作關(guān)鍵狀態(tài)的標(biāo)識(shí)。

3. 崩潰或程序未定義行為

由于數(shù)據(jù)競(jìng)爭(zhēng)或者不一致的狀態(tài),程序可能會(huì)進(jìn)入一個(gè)不可預(yù)測(cè)的狀態(tài),導(dǎo)致崩潰。全局變量的值在多線程的競(jìng)爭(zhēng)中可能會(huì)發(fā)生損壞,從而導(dǎo)致未定義的行為(undefined behavior)。

例如:

  • 訪問(wèn)已釋放內(nèi)存:一個(gè)線程修改了全局變量并釋放了相關(guān)內(nèi)存,但其他線程仍然試圖訪問(wèn)該內(nèi)存。
  • 內(nèi)存覆蓋:多個(gè)線程同時(shí)修改全局變量,導(dǎo)致不同線程的操作互相覆蓋,從而引發(fā)崩潰。

二、互斥鎖std::mutex實(shí)現(xiàn)同步

std::mutex 是C++標(biāo)準(zhǔn)庫(kù)中的一種機(jī)制,用于避免多個(gè)線程同時(shí)訪問(wèn)同一個(gè)資源(如全局變量)時(shí)發(fā)生競(jìng)爭(zhēng)條件。

下面是一個(gè)示例,展示了如何使用std::mutex來(lái)保護(hù)全局變量:

#include <iostream>
#include <thread>
#include <mutex>

std::mutex mtx;  // 定義全局互斥鎖
int globalVar = 0;  // 定義全局變量

void threadFunction() {
    std::lock_guard<std::mutex> lock(mtx);  // 上鎖,確?;コ?
    // 訪問(wèn)和修改全局變量
    ++globalVar;
    std::cout << "Global variable: " << globalVar << std::endl;
    // 鎖會(huì)在lock_guard離開(kāi)作用域時(shí)自動(dòng)釋放
}

int main() {
    std::thread t1(threadFunction);
    std::thread t2(threadFunction);

    t1.join();
    t2.join();

    return 0;
}

說(shuō)明:

  • std::mutex: 用于保護(hù)共享資源(如全局變量)。
  • std::lock_guard<std::mutex>: 是一個(gè)RAII風(fēng)格的封裝器,它在構(gòu)造時(shí)自動(dòng)上鎖,在析構(gòu)時(shí)自動(dòng)解鎖,確保了線程安全。
  • threadFunction中,每個(gè)線程在訪問(wèn)globalVar之前都會(huì)先獲得互斥鎖,這樣就能確保線程之間不會(huì)同時(shí)訪問(wèn)和修改全局變量。

使用std::mutex可以防止不同線程之間因競(jìng)爭(zhēng)訪問(wèn)全局變量而引發(fā)的錯(cuò)誤或不一致問(wèn)題。

有時(shí)如果你需要更細(xì)粒度的控制,還可以考慮使用std::unique_lock,它比std::lock_guard更靈活,允許手動(dòng)控制鎖的獲取和釋放。

三、獨(dú)占鎖std::unique_lock實(shí)現(xiàn)同步

std::unique_lock 是 C++11 標(biāo)準(zhǔn)庫(kù)中的一種互斥鎖包裝器,它提供了比 std::lock_guard 更靈活的鎖管理方式。std::unique_lock 允許手動(dòng)控制鎖的獲取和釋放,而不僅僅是在對(duì)象生命周期結(jié)束時(shí)自動(dòng)釋放鎖(如 std::lock_guard 所做的那樣)。這使得它比 std::lock_guard 更加靈活,適用于更復(fù)雜的場(chǎng)景,比如需要在同一作用域內(nèi)多次鎖定或解鎖,或者需要在鎖定期間進(jìn)行一些其他操作。

std::unique_lock 的關(guān)鍵特性:

  • 手動(dòng)控制鎖的獲取和釋放:std::unique_lock 支持手動(dòng)解鎖和重新鎖定,它比 std::lock_guard 更加靈活。
  • 延遲鎖定和提前解鎖:你可以選擇在對(duì)象創(chuàng)建時(shí)延遲鎖定,或者在鎖定后手動(dòng)釋放鎖。
  • 支持條件變量:std::unique_lock 支持與條件變量一起使用,這是 std::lock_guard 無(wú)法做到的。

基本用法:

1. 構(gòu)造時(shí)自動(dòng)加鎖:

std::unique_lock 默認(rèn)會(huì)在構(gòu)造時(shí)自動(dòng)加鎖。

#include <iostream>
#include <thread>
#include <mutex>

std::mutex mtx;

void threadFunction() {
    std::unique_lock<std::mutex> lock(mtx);  // 構(gòu)造時(shí)自動(dòng)上鎖
    std::cout << "Thread is running\n";
    // 臨界區(qū)的操作
    // 鎖會(huì)在 lock 對(duì)象超出作用域時(shí)自動(dòng)釋放
}

int main() {
    std::thread t1(threadFunction);
    std::thread t2(threadFunction);

    t1.join();
    t2.join();

    return 0;
}

2. 手動(dòng)解鎖與重新加鎖:

std::unique_lock 允許你在鎖定期間手動(dòng)解鎖和重新加鎖,這對(duì)于一些需要臨時(shí)釋放鎖的場(chǎng)景非常有用。

#include <iostream>
#include <thread>
#include <mutex>

std::mutex mtx;

void threadFunction() {
    std::unique_lock<std::mutex> lock(mtx);  // 構(gòu)造時(shí)自動(dòng)上鎖
    std::cout << "Thread is running\n";
    
    // 臨界區(qū)的操作
    lock.unlock();  // 手動(dòng)解鎖
    
    std::cout << "Lock released temporarily\n";
    
    // 臨界區(qū)之外的操作
    
    lock.lock();  // 重新加鎖
    
    std::cout << "Lock acquired again\n";
    // 臨界區(qū)操作繼續(xù)進(jìn)行
}

int main() {
    std::thread t1(threadFunction);
    std::thread t2(threadFunction);

    t1.join();
    t2.join();

    return 0;
}

3. 延遲鎖定:

std::unique_lock 也允許你延遲鎖定,通過(guò)傳遞一個(gè) std::defer_lock 參數(shù)給構(gòu)造函數(shù)來(lái)實(shí)現(xiàn)。這會(huì)創(chuàng)建一個(gè)未鎖定的 std::unique_lock,你可以在稍后手動(dòng)調(diào)用 lock() 來(lái)加鎖。

#include <iostream>
#include <thread>
#include <mutex>

std::mutex mtx;

void threadFunction() {
    std::unique_lock<std::mutex> lock(mtx, std::defer_lock);  // 延遲加鎖
    std::cout << "Thread is preparing to run\n";
    
    // 做一些不需要加鎖的操作
    
    lock.lock();  // 手動(dòng)加鎖
    std::cout << "Thread is running under lock\n";
    
    // 臨界區(qū)的操作
}

int main() {
    std::thread t1(threadFunction);
    std::thread t2(threadFunction);

    t1.join();
    t2.join();

    return 0;
}

4. 條件變量:

std::unique_lock 是與條件變量一起使用的理想選擇,它支持對(duì)互斥鎖的手動(dòng)解鎖和重新加鎖。這在條件變量的使用場(chǎng)景中非常有用,因?yàn)樵诘却龡l件時(shí)需要解鎖互斥鎖,而在條件滿足時(shí)重新加鎖。

#include <iostream>
#include <thread>
#include <mutex>
#include <condition_variable>

std::mutex mtx;
std::condition_variable cv;
bool ready = false;

void threadFunction() {
    std::unique_lock<std::mutex> lock(mtx);  // 上鎖
    while (!ready) {  // 等待 ready 為 true
        cv.wait(lock);  // 等待,自動(dòng)解鎖并掛起線程
    }
    std::cout << "Thread is running\n";
}

void notify() {
    std::this_thread::sleep_for(std::chrono::seconds(1));  // 模擬一些操作
    std::cout << "Notifying the threads\n";
    std::unique_lock<std::mutex> lock(mtx);  // 上鎖
    ready = true;
    cv.notify_all();  // 通知所有線程
}

int main() {
    std::thread t1(threadFunction);
    std::thread t2(threadFunction);

    std::thread notifier(notify);
    
    t1.join();
    t2.join();
    notifier.join();

    return 0;
}

解釋:

  • std::condition_variable 和 std::unique_lock

    • 在 threadFunction 中,cv.wait(lock) 會(huì)釋放鎖并等待條件變量的通知。
    • std::unique_lock 能夠在調(diào)用 wait 時(shí)自動(dòng)釋放鎖,并且在 wait 返回時(shí)會(huì)重新加鎖,這使得 std::unique_lock 成為使用條件變量的最佳選擇。
  • cv.notify_all():通知所有等待該條件的線程,thread1 和 thread2 都會(huì)在條件滿足時(shí)繼續(xù)執(zhí)行。

四、共享鎖std::shared_mutex實(shí)現(xiàn)同步

std::shared_mutex 是 C++17 引入的一個(gè)同步原語(yǔ),它提供了一種讀寫(xiě)鎖機(jī)制,允許多個(gè)線程共享讀取同一資源,而只有一個(gè)線程能夠獨(dú)占寫(xiě)入該資源。相比于傳統(tǒng)的 std::mutex(只支持獨(dú)占鎖),std::shared_mutex 可以提高并發(fā)性,特別是在讀操作遠(yuǎn)多于寫(xiě)操作的情況下。

std::shared_mutex 的工作原理:

  • 共享鎖(shared lock):多個(gè)線程可以同時(shí)獲取共享鎖,這意味著多個(gè)線程可以同時(shí)讀取共享資源。多個(gè)線程獲取共享鎖時(shí)不會(huì)發(fā)生沖突。
  • 獨(dú)占鎖(unique lock):只有一個(gè)線程可以獲取獨(dú)占鎖,這意味著寫(xiě)操作會(huì)阻塞其他所有操作(無(wú)論是讀操作還是寫(xiě)操作),以保證數(shù)據(jù)的一致性。

使用 std::shared_mutex:

std::shared_mutex 提供了兩種類型的鎖:

  • std::unique_lock<std::shared_mutex>:用于獲取獨(dú)占鎖。
  • std::shared_lock<std::shared_mutex>:用于獲取共享鎖。

1. 基本使用示例:

#include <iostream>
#include <thread>
#include <shared_mutex>
#include <vector>

std::shared_mutex mtx;  // 定義一個(gè) shared_mutex
int sharedData = 0;

void readData(int threadId) {
    std::shared_lock<std::shared_mutex> lock(mtx);  // 獲取共享鎖
    std::cout << "Thread " << threadId << " is reading data: " << sharedData << std::endl;
}

void writeData(int threadId, int value) {
    std::unique_lock<std::shared_mutex> lock(mtx);  // 獲取獨(dú)占鎖
    sharedData = value;
    std::cout << "Thread " << threadId << " is writing data: " << sharedData << std::endl;
}

int main() {
    std::vector<std::thread> threads;

    // 啟動(dòng)多個(gè)線程進(jìn)行讀取操作
    for (int i = 0; i < 5; ++i) {
        threads.push_back(std::thread(readData, i));
    }

    // 啟動(dòng)一個(gè)線程進(jìn)行寫(xiě)入操作
    threads.push_back(std::thread(writeData, 100, 42));

    // 等待所有線程結(jié)束
    for (auto& t : threads) {
        t.join();
    }

    return 0;
}

解釋:

  • 共享鎖 (std::shared_lock):線程 readData 使用 std::shared_lock 獲取共享鎖,這允許多個(gè)線程同時(shí)讀取 sharedData,因?yàn)樽x取操作是線程安全的。
  • 獨(dú)占鎖 (std::unique_lock):線程 writeData 使用 std::unique_lock 獲取獨(dú)占鎖,這確保了只有一個(gè)線程可以寫(xiě) sharedData,并且寫(xiě)操作會(huì)阻塞所有其他線程(包括讀操作和寫(xiě)操作)。

2. 多個(gè)讀線程與單個(gè)寫(xiě)線程的并發(fā)控制:

在這個(gè)示例中,多個(gè)讀線程可以并行執(zhí)行,因?yàn)樗鼈兌极@取了共享鎖。只有當(dāng)寫(xiě)線程(獲取獨(dú)占鎖)執(zhí)行時(shí),其他線程(無(wú)論是讀線程還是寫(xiě)線程)會(huì)被阻塞。

  • 寫(xiě)操作:獲取獨(dú)占鎖,所有讀操作和寫(xiě)操作都會(huì)被阻塞,直到寫(xiě)操作完成。
  • 讀操作:多個(gè)線程可以同時(shí)獲取共享鎖,只有在沒(méi)有寫(xiě)操作時(shí)才會(huì)執(zhí)行。

3. 共享鎖與獨(dú)占鎖的沖突:

  • 共享鎖:多個(gè)線程可以同時(shí)獲取共享鎖,只要沒(méi)有線程持有獨(dú)占鎖。共享鎖不會(huì)阻塞其他共享鎖請(qǐng)求。
  • 獨(dú)占鎖:當(dāng)一個(gè)線程持有獨(dú)占鎖時(shí),其他任何線程的共享鎖或獨(dú)占鎖請(qǐng)求都會(huì)被阻塞,直到獨(dú)占鎖釋放。

4. 使用場(chǎng)景:

std::shared_mutex 主要適用于讀多寫(xiě)少的場(chǎng)景。假設(shè)有一個(gè)資源(如緩存、數(shù)據(jù)結(jié)構(gòu)),它在大部分時(shí)間內(nèi)被多個(gè)線程讀取,但偶爾需要被更新。在這種情況下,std::shared_mutex 可以讓多個(gè)讀操作并行執(zhí)行,同時(shí)避免寫(xiě)操作導(dǎo)致的不必要的阻塞。

例如:

  • 緩存數(shù)據(jù)讀取:多個(gè)線程可以并發(fā)讀取緩存中的數(shù)據(jù),而當(dāng)緩存需要更新時(shí),獨(dú)占鎖會(huì)確保數(shù)據(jù)一致性。
  • 數(shù)據(jù)庫(kù)的并發(fā)查詢和修改:多個(gè)線程可以并發(fā)查詢數(shù)據(jù)庫(kù),但只有一個(gè)線程可以執(zhí)行寫(xiě)操作。

5. std::shared_mutex 與 std::mutex 比較:

  • std::mutex:提供獨(dú)占鎖,適用于寫(xiě)操作頻繁且不需要并發(fā)讀的場(chǎng)景。每次加鎖時(shí),其他線程都無(wú)法進(jìn)入臨界區(qū)。
  • std::shared_mutex:適用于讀多寫(xiě)少的場(chǎng)景,允許多個(gè)線程同時(shí)讀取共享資源,但寫(xiě)操作會(huì)阻塞所有其他操作。

6. 性能考慮:

  • 讀操作頻繁時(shí):使用 std::shared_mutex 可以提高并發(fā)性,因?yàn)槎鄠€(gè)線程可以同時(shí)讀取數(shù)據(jù)。
  • 寫(xiě)操作頻繁時(shí):性能可能會(huì)低于 std::mutex,因?yàn)閷?xiě)操作需要獨(dú)占資源并阻塞所有其他操作。

7. 條件變量:

與 std::mutex 一樣,std::shared_mutex 也可以與條件變量(std::condition_variable)一起使用,不過(guò)在使用時(shí)要注意,不同的線程需要加鎖和解鎖對(duì)應(yīng)的鎖。

#include <iostream>
#include <thread>
#include <shared_mutex>
#include <condition_variable>

std::shared_mutex mtx;
std::condition_variable_any cv;
int sharedData = 0;

void readData() {
    std::shared_lock<std::shared_mutex> lock(mtx);  // 獲取共享鎖
    while (sharedData == 0) {  // 等待數(shù)據(jù)可用
        cv.wait(lock);  // 等待數(shù)據(jù)被寫(xiě)入
    }
    std::cout << "Reading data: " << sharedData << std::endl;
}

void writeData(int value) {
    std::unique_lock<std::shared_mutex> lock(mtx);  // 獲取獨(dú)占鎖
    sharedData = value;
    std::cout << "Writing data: " << sharedData << std::endl;
    cv.notify_all();  // 通知所有等待的線程
}

int main() {
    std::thread reader(readData);
    std::thread writer(writeData, 42);

    reader.join();
    writer.join();

    return 0;
}

解釋:

  • std::shared_lock:用于共享讀鎖,允許多個(gè)線程同時(shí)讀取。
  • cv.wait(lock):使用共享鎖來(lái)等待某些條件的變化。
  • cv.notify_all():通知所有等待線程,喚醒它們繼續(xù)執(zhí)行。

五、std::atomic實(shí)現(xiàn)同步

std::atomic 是 C++11 標(biāo)準(zhǔn)引入的一種類型,用于實(shí)現(xiàn)原子操作。原子操作指的是操作在執(zhí)行過(guò)程中不可被中斷,因此能夠保證數(shù)據(jù)的一致性和正確性。

std::atomic 提供了一些基本的原子操作方法,這些操作是不可分割的,保證了在多線程環(huán)境下線程安全。它主要用于數(shù)據(jù)的同步與協(xié)作,避免了傳統(tǒng)同步原語(yǔ)(如鎖、條件變量)所帶來(lái)的性能瓶頸。

原子操作的基本概念:

  • 原子性:在執(zhí)行時(shí),操作不能被打斷,保證線程之間對(duì)共享變量的操作不會(huì)產(chǎn)生競(jìng)態(tài)條件。
  • 內(nèi)存順序(Memory Ordering):控制操作的執(zhí)行順序和對(duì)共享數(shù)據(jù)的可見(jiàn)性,std::atomic 允許通過(guò)內(nèi)存順序來(lái)顯式指定不同線程間的同步行為。

std::atomic 提供的原子操作:

  • 加載(Load):從原子變量中讀取數(shù)據(jù)。
  • 存儲(chǔ)(Store):將數(shù)據(jù)存儲(chǔ)到原子變量中。

std::atomic 支持的內(nèi)存順序(Memory Ordering):

  • std::memory_order_acquire:確保前面的操作在加載之后執(zhí)行,即它會(huì)阻止后續(xù)的操作在此之前執(zhí)行。
  • std::memory_order_release:確保后面的操作在存儲(chǔ)之前執(zhí)行,即它會(huì)阻止前面的操作在此之后執(zhí)行。

通常情況下,在使用 std::atomic 進(jìn)行同步時(shí),使用 memory_order_release 在 store 操作時(shí),使用 memory_order_acquire 在 load 操作時(shí),是一種常見(jiàn)的模式,特別是在生產(chǎn)者-消費(fèi)者模式或者其他類似的同步模式下。

memory_order_release 和 memory_order_acquire 一般搭配使用。

這種組合是為了確保 內(nèi)存順序的一致性,并且保證數(shù)據(jù)正確的可見(jiàn)性。具體來(lái)說(shuō):

  • memory_order_release:在執(zhí)行 store 操作時(shí),它會(huì)確保在 store 之前的所有操作(如數(shù)據(jù)寫(xiě)入)不會(huì)被重排序到 store 之后,保證當(dāng)前線程的寫(xiě)操作對(duì)其他線程是可見(jiàn)的。因此,store 操作保證所有前置的寫(xiě)操作都會(huì)在這個(gè) store 完成后被其他線程看到。

  • memory_order_acquire:在執(zhí)行 load 操作時(shí),它會(huì)確保在 load 之后的所有操作(如數(shù)據(jù)讀?。┎粫?huì)被重排序到 load 之前,保證當(dāng)前線程在讀取共享數(shù)據(jù)后,后續(xù)的操作可以看到正確的數(shù)據(jù)。在 load 之前的所有操作(包括對(duì)共享變量的寫(xiě)入)會(huì)在讀取這個(gè)值之后對(duì)當(dāng)前線程可見(jiàn)。

這兩者配合使用,確保了線程間的同步,避免了數(shù)據(jù)競(jìng)態(tài)條件。

具體場(chǎng)景

考慮一個(gè)生產(chǎn)者-消費(fèi)者模型,生產(chǎn)者負(fù)責(zé)寫(xiě)入數(shù)據(jù)并通知消費(fèi)者,消費(fèi)者負(fù)責(zé)讀取數(shù)據(jù)并處理。

示例:

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

std::atomic<int> data(0);
std::atomic<bool> ready(false);

void consumer() {
    while (!ready.load(std::memory_order_acquire)) {
        // 等待 ready 為 true
    }
    std::cout << "Data: " << data.load(std::memory_order_relaxed) << std::endl;
}

void producer() {
    data.store(42, std::memory_order_relaxed);  // 寫(xiě)數(shù)據(jù)
    ready.store(true, std::memory_order_release);  // 設(shè)置 ready 為 true
}

int main() {
    std::thread t1(consumer);
    std::thread t2(producer);

    t1.join();
    t2.join();

    return 0;
}

解釋:

  • ready.store(true, std::memory_order_release):生產(chǎn)者線程在寫(xiě)入 ready 時(shí)使用 memory_order_release,這意味著在 ready 設(shè)置為 true 之后,所有在此之前的操作(如對(duì) data 的寫(xiě)入)對(duì)消費(fèi)者線程是可見(jiàn)的。

  • ready.load(std::memory_order_acquire):消費(fèi)者線程在讀取 ready 時(shí)使用 memory_order_acquire,這意味著消費(fèi)者線程在讀取 ready 后,確保它能夠看到生產(chǎn)者線程在 store ready 之前所做的所有修改(如 data 的值)。

這種組合保證了生產(chǎn)者線程的寫(xiě)操作(例如 data.store(42))對(duì)于消費(fèi)者線程是可見(jiàn)的,且在讀取 ready 后,消費(fèi)者線程可以安全地讀取到更新后的 data

到此這篇關(guān)于C++實(shí)現(xiàn)多線程并發(fā)場(chǎng)景下的同步方法的文章就介紹到這了,更多相關(guān)C++ 多線程并發(fā)同步內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

  • 淺談C語(yǔ)言之字符串處理函數(shù)

    淺談C語(yǔ)言之字符串處理函數(shù)

    下面小編就為大家?guī)?lái)一篇淺談C語(yǔ)言之字符串處理函數(shù)。小編覺(jué)得挺不錯(cuò)的,現(xiàn)在就分享給大家,也給大家做個(gè)參考。一起跟隨小編過(guò)來(lái)看看吧
    2016-08-08
  • C/C++實(shí)現(xiàn)線性順序表的示例代碼

    C/C++實(shí)現(xiàn)線性順序表的示例代碼

    使用順序存儲(chǔ)結(jié)構(gòu)的線性存儲(chǔ)結(jié)構(gòu)的表為線性順序表。本文將分別利用C語(yǔ)言和C++實(shí)現(xiàn)線性順序表,文中示例代碼講解詳細(xì),需要的可以參考一下
    2022-05-05
  • C++中類的轉(zhuǎn)換函數(shù)你了解嗎

    C++中類的轉(zhuǎn)換函數(shù)你了解嗎

    這篇文章主要為大家詳細(xì)介紹了C++中類的轉(zhuǎn)換函數(shù),文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下,希望能夠給你帶來(lái)幫助
    2022-03-03
  • C++ Invalidaterect()函數(shù)作用案例詳解

    C++ Invalidaterect()函數(shù)作用案例詳解

    這篇文章主要介紹了C++ Invalidaterect()函數(shù)作用案例詳解,本篇文章通過(guò)簡(jiǎn)要的案例,講解了該項(xiàng)技術(shù)的了解與使用,以下就是詳細(xì)內(nèi)容,需要的朋友可以參考下
    2021-08-08
  • Qt中QTextEdit和QPlainTextEdit控件的實(shí)現(xiàn)

    Qt中QTextEdit和QPlainTextEdit控件的實(shí)現(xiàn)

    本文主要介紹了Qt中QTextEdit和QPlainTextEdit控件的實(shí)現(xiàn),文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧
    2025-04-04
  • C++詳細(xì)分析lambda表達(dá)式的本質(zhì)

    C++詳細(xì)分析lambda表達(dá)式的本質(zhì)

    Lambda表達(dá)式是現(xiàn)代C++在C ++ 11和更高版本中的一個(gè)新的語(yǔ)法糖 ,在C++11、C++14、C++17和C++20中Lambda表達(dá)的內(nèi)容還在不斷更新。 lambda表達(dá)式(也稱為lambda函數(shù))是在調(diào)用或作為函數(shù)參數(shù)傳遞的位置處定義匿名函數(shù)對(duì)象的便捷方法
    2022-06-06
  • C語(yǔ)言深入分析浮點(diǎn)型數(shù)據(jù)存儲(chǔ)

    C語(yǔ)言深入分析浮點(diǎn)型數(shù)據(jù)存儲(chǔ)

    使用編程語(yǔ)言進(jìn)行編程時(shí),需要用到各種變量來(lái)存儲(chǔ)各種信息。變量保留的是它所存儲(chǔ)的值的內(nèi)存位置。這意味著,當(dāng)您創(chuàng)建一個(gè)變量時(shí),就會(huì)在內(nèi)存中保留一些空間。您可能需要存儲(chǔ)各種數(shù)據(jù)類型的信息,操作系統(tǒng)會(huì)根據(jù)變量的數(shù)據(jù)類型,來(lái)分配內(nèi)存和決定在保留內(nèi)存中存儲(chǔ)什么
    2022-08-08
  • C語(yǔ)言修煉之路函數(shù)篇真題訓(xùn)練上

    C語(yǔ)言修煉之路函數(shù)篇真題訓(xùn)練上

    函數(shù)是一組一起執(zhí)行一個(gè)任務(wù)的語(yǔ)句。每個(gè)?C?程序都至少有一個(gè)函數(shù),即主函數(shù)?main()?,所有簡(jiǎn)單的程序都可以定義其他額外的函數(shù)
    2022-03-03
  • 一篇文章徹底弄懂C++虛函數(shù)的實(shí)現(xiàn)機(jī)制

    一篇文章徹底弄懂C++虛函數(shù)的實(shí)現(xiàn)機(jī)制

    C++中的虛函數(shù)的作用主要是實(shí)現(xiàn)了多態(tài)的機(jī)制,基類定義虛函數(shù),子類可以重寫(xiě)該函數(shù),在派生類中對(duì)基類定義的虛函數(shù)進(jìn)行重寫(xiě)時(shí),需要在派生類中聲明該方法為虛方法,這篇文章主要給大家介紹了關(guān)于如何通過(guò)一篇文章徹底弄懂C++虛函數(shù)的實(shí)現(xiàn)機(jī)制,需要的朋友可以參考下
    2021-06-06
  • C++之string類對(duì)象的容量操作詳解

    C++之string類對(duì)象的容量操作詳解

    通過(guò)在網(wǎng)站上的資料搜集,得到了很多關(guān)于string類對(duì)象的容量操作,通過(guò)對(duì)這些資料的整理和加入一些自己的代碼,希望能夠給你帶來(lái)幫助
    2021-08-08

最新評(píng)論