最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

C++中線程同步與互斥的四種方式介紹及對比詳解

 更新時(shí)間:2025年01月14日 10:06:26   作者:碼事漫談  
在C++中,當(dāng)兩個(gè)或更多的線程需要訪問共享數(shù)據(jù)時(shí),就會出現(xiàn)線程安全問題,這是因?yàn)?如果沒有適當(dāng)?shù)耐綑C(jī)制,一個(gè)線程可能在另一個(gè)線程還沒有完成對數(shù)據(jù)的修改就開始訪問數(shù)據(jù),這將導(dǎo)致數(shù)據(jù)的不一致性和程序的不可預(yù)測性,本文介紹了C++中線程同步與互斥的四種方式介紹及對比

引言

在C++中,當(dāng)兩個(gè)或更多的線程需要訪問共享數(shù)據(jù)時(shí),就會出現(xiàn)線程安全問題。這是因?yàn)?,如果沒有適當(dāng)?shù)耐綑C(jī)制,一個(gè)線程可能在另一個(gè)線程還沒有完成對數(shù)據(jù)的修改就開始訪問數(shù)據(jù),這將導(dǎo)致數(shù)據(jù)的不一致性和程序的不可預(yù)測性。為了解決這個(gè)問題,C++提供了多種線程同步和互斥的機(jī)制。

1. 互斥量(Mutex)

互斥量是一種同步機(jī)制,用于防止多個(gè)線程同時(shí)訪問共享資源。在C++中,可以使用std::mutex類來創(chuàng)建互斥量。

#include <thread>
#include <mutex>

std::mutex mtx;  // 全局互斥量
int shared_data = 0;  // 共享數(shù)據(jù)

void thread_func() {
    for (int i = 0; i < 10000; ++i) {
        mtx.lock();  // 獲取互斥量的所有權(quán)
        ++shared_data;  // 修改共享數(shù)據(jù)
        mtx.unlock();  // 釋放互斥量的所有權(quán)
    }
}

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

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

    std::cout << shared_data << std::endl;  // 輸出20000

    return 0;
}

在上述代碼中,我們創(chuàng)建了一個(gè)全局互斥量mtx和一個(gè)共享數(shù)據(jù)shared_data。然后,我們在thread_func函數(shù)中使用mtx.lock()和mtx.unlock()來保護(hù)對shared_data的訪問,確保在任何時(shí)候只有一個(gè)線程可以修改shared_data。

2. 鎖(Lock)

除了直接使用互斥量,C++還提供了std::lock_guard和std::unique_lock兩種鎖,用于自動管理互斥量的所有權(quán)。

#include <thread>
#include <mutex>

std::mutex mtx;  // 全局互斥量
int shared_data = 0;  // 共享數(shù)據(jù)

void thread_func() {
    for (int i = 0; i < 10000; ++i) {
        std::lock_guard<std::mutex> lock(mtx);  // 創(chuàng)建鎖,自動獲取互斥量的所有權(quán)
        ++shared_data;  // 修改共享數(shù)據(jù)
        // 鎖在離開作用域時(shí)自動釋放互斥量的所有權(quán)
    }
}

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

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

    std::cout << shared_data << std::endl;  // 輸出20000

    return 0;
}

在上述代碼中,我們使用std::lock_guard來自動管理互斥量的所有權(quán)。當(dāng)創(chuàng)建std::lock_guard對象時(shí),它會自動獲取互斥量的所有權(quán),當(dāng)std::lock_guard對象離開作用域時(shí),它會自動釋放互斥量的所有權(quán)。這樣,我們就不需要手動調(diào)用mtx.lock()和mtx.unlock(),可以避免因忘記釋放互斥量而導(dǎo)致的死鎖。

3. 條件變量(Condition Variable)

條件變量是一種同步機(jī)制,用于在多個(gè)線程之間同步條件的變化。在C++中,可以使用std::condition_variable類來創(chuàng)建條件變量。

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

std::mutex mtx;  // 全局互斥量
std::condition_variable cv;  // 全局條件變量
bool ready = false;  // 共享?xiàng)l件

void print_id(int id) {
    std::unique_lock<std::mutex> lock(mtx);  // 創(chuàng)建鎖,自動獲取互斥量的所有權(quán)
    while (!ready) {  // 如果條件不滿足
        cv.wait(lock);  // 等待條件變量的通知
    }
    // 當(dāng)收到條件變量的通知,且條件滿足時(shí),繼續(xù)執(zhí)行
    std::cout << "thread " << id << '\n';
}

void go() {
    std::unique_lock<std::mutex> lock(mtx);  // 創(chuàng)建鎖,自動獲取互斥量的所有權(quán)
    ready = true;  // 修改共享?xiàng)l件
    cv.notify_all();  // 通知所有等待的線程
}

int main() {
    std::thread threads[10];
    for (int i = 0; i < 10; ++i)
        threads[i] = std::thread(print_id, i);

    std::cout << "10 threads ready to race...\n";
    go();  // 開始比賽

    for (auto& th : threads) th.join();

    return 0;
}

在上述代碼中,我們創(chuàng)建了一個(gè)全局互斥量mtx、一個(gè)全局條件變量cv和一個(gè)共享?xiàng)l件ready。然后,我們在print_id函數(shù)中使用cv.wait(lock)來等待條件變量的通知,當(dāng)收到條件變量的通知,且條件滿足時(shí),繼續(xù)執(zhí)行。在go函數(shù)中,我們修改共享?xiàng)l件,并使用cv.notify_all()來通知所有等待的線程。

4. 原子操作(Atomic Operation)

原子操作是一種特殊的操作,它可以在多線程環(huán)境中安全地對數(shù)據(jù)進(jìn)行讀寫,而無需使用互斥量或鎖。在C++中,可以使用std::atomic模板類來創(chuàng)建原子類型。

#include <thread>
#include <atomic>

std::atomic<int> shared_data(0);  // 共享數(shù)據(jù)

void thread_func() {
    for (int i = 0; i < 10000; ++i) {
        ++shared_data;  // 原子操作
    }
}

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

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

    std::cout << shared_data << std::endl;  // 輸出20000

    return 0;
}

在上述代碼中,我們創(chuàng)建了一個(gè)原子類型的共享數(shù)據(jù)shared_data。然后,我們在thread_func函數(shù)中使用++shared_data來進(jìn)行原子操作,這樣,我們就不需要使用互斥量或鎖,也可以保證在任何時(shí)候只有一個(gè)線程可以修改shared_data。

5. 對比

策略優(yōu)點(diǎn)缺點(diǎn)
單一全局互斥量簡單可能導(dǎo)致嚴(yán)重的性能問題,降低并發(fā)性
多個(gè)互斥量提高并發(fā)性增加程序復(fù)雜性,需要避免死鎖
原子操作提高并發(fā)性,避免互斥量開銷增加程序復(fù)雜性,需要理解和使用原子操作
讀寫鎖提高并發(fā)性,特別是讀操作多于寫操作時(shí)增加程序復(fù)雜性,需要管理讀寫鎖,需要避免死鎖

案例舉例

假設(shè)我們正在開發(fā)一個(gè)在線聊天 服務(wù)器,需要處理大量的并發(fā)連接。每個(gè)連接都有一個(gè)關(guān)聯(lián)的用戶對象,用戶對象包含了用戶的狀態(tài)信息,如用戶名、在線狀態(tài)等。

在這種情況下,我們可以使用多個(gè)互斥量的策略。我們可以將用戶對象劃分為幾個(gè)組,每個(gè)組有一個(gè)關(guān)聯(lián)的互斥量。當(dāng)一個(gè)線程需要訪問一個(gè)用戶對象時(shí),它只需要鎖定該用戶對象所在組的互斥量,而不是所有的用戶對象。這樣,不同的線程可以同時(shí)訪問不同的用戶對象,從而提高并發(fā)性。

同時(shí),我們也可以使用讀寫鎖的策略。因?yàn)樵诖蠖鄶?shù)情況下,線程只需要讀取用戶的狀態(tài)信息,而不需要修改。所以,我們可以使用讀寫鎖,允許多個(gè)線程同時(shí)讀取用戶對象,但在修改用戶對象時(shí)需要獨(dú)占鎖。

在實(shí)踐中,我們可能需要結(jié)合使用這兩種策略,以達(dá)到最佳的效果。

6. 更進(jìn)一步:原子操作+鎖

原子操作和鎖是兩種不同的線程同步機(jī)制,它們可以單獨(dú)使用,也可以一起使用,具體取決于你的應(yīng)用場景。

原子操作是一種低級的同步機(jī)制,它可以保證對單個(gè)內(nèi)存位置的讀寫操作是原子的,即在任何時(shí)候只有一個(gè)線程可以對內(nèi)存位置進(jìn)行操作。原子操作通常用于實(shí)現(xiàn)高級的同步機(jī)制,如鎖和條件變量。

鎖是一種高級的同步機(jī)制,它可以保證對一段代碼或多個(gè)內(nèi)存位置的訪問是原子的,即在任何時(shí)候只有一個(gè)線程可以執(zhí)行被鎖保護(hù)的代碼或訪問被鎖保護(hù)的內(nèi)存位置。

如果你在使用鎖的同時(shí)還使用原子操作,那么你需要確保你的代碼正確地理解和使用這兩種同步機(jī)制。例如,如果你在一個(gè)被鎖保護(hù)的代碼段中使用原子操作,那么你需要確保原子操作不會違反鎖的語義,即在任何時(shí)候只有一個(gè)線程可以執(zhí)行被鎖保護(hù)的代碼。

以下是一個(gè)使用原子操作和鎖的例子:

#include <thread>
#include <mutex>
#include <atomic>

std::mutex mtx;  // 全局互斥量
std::atomic<int> counter(0);  // 原子計(jì)數(shù)器

void thread_func() {
    for (int i = 0; i < 10000; ++i) {
        std::lock_guard<std::mutex> lock(mtx);  // 獲取互斥量的所有權(quán)
        ++counter;  // 原子操作
        // 鎖在離開作用域時(shí)自動釋放互斥量的所有權(quán)
    }
}

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

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

    std::cout << counter << std::endl;  // 輸出20000

    return 0;
}

在上述代碼中,我們使用std::lock_guard來獲取互斥量的所有權(quán),然后使用++counter來進(jìn)行原子操作。這樣,我們既保證了在任何時(shí)候只有一個(gè)線程可以執(zhí)行被鎖保護(hù)的代碼,也保證了對counter的操作是原子的。

總的來說,原子操作和鎖可以一起使用,但你需要確保你的代碼正確地理解和使用這兩種同步機(jī)制。

總結(jié)

在C++中,當(dāng)兩個(gè)或更多的線程需要訪問共享數(shù)據(jù)時(shí),可以使用互斥量、鎖、條件變量和原子操作等多種線程同步和互斥的機(jī)制來保證線程安全。選擇哪種機(jī)制,取決于具體的應(yīng)用場景和需求。

以上就是C++中線程同步與互斥的四種方式介紹及對比詳解的詳細(xì)內(nèi)容,更多關(guān)于C++線程同步與互斥方式的資料請關(guān)注腳本之家其它相關(guān)文章!

相關(guān)文章

最新評論

乌拉特中旗| 东乌珠穆沁旗| 晋中市| 银川市| 邛崃市| 巴青县| 长治县| 平山县| 尼木县| 商洛市| 离岛区| 古浪县| 邯郸市| 上林县| 安图县| 托克逊县| 凤庆县| 青神县| 特克斯县| 鹿邑县| 西昌市| 五原县| 七台河市| 莱芜市| 双柏县| 巴林左旗| 微山县| 寻乌县| 商都县| 清原| 萍乡市| 安顺市| 雷州市| 博兴县| 三门峡市| 改则县| 筠连县| 宜春市| 漠河县| 论坛| 安溪县|