欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

c++ 標(biāo)準(zhǔn)庫多線程問題小結(jié)

 更新時(shí)間:2025年03月12日 09:17:59   作者:云山漫卷  
C++11 引入了<thread>庫,使得多線程編程更加方便,以下是一些基本概念和示例,幫助你理解如何在 C++ 中進(jìn)行多線程編程,這篇文章主要介紹了c++ 標(biāo)準(zhǔn)庫多線程,需要的朋友可以參考下

C++ 多線程編程允許程序同時(shí)執(zhí)行多個(gè)任務(wù),從而提高性能和響應(yīng)能力。C++11 引入了 <thread> 庫,使得多線程編程更加方便。以下是一些基本概念和示例,幫助你理解如何在 C++ 中進(jìn)行多線程編程。

1. 創(chuàng)建線程

使用 std::thread 類可以創(chuàng)建一個(gè)新線程。你需要將一個(gè)函數(shù)或可調(diào)用對(duì)象傳遞給 std::thread 構(gòu)造函數(shù)。

#include <iostream>
#include <thread>
void threadFunction() {
    std::cout << "Hello from thread!\\\\n";
}
int main() {
    std::thread t(threadFunction);  // 創(chuàng)建線程并執(zhí)行 threadFunction
    t.join();  // 等待線程結(jié)束
    std::cout << "Hello from main!\\\\n";
    return 0;
}

2. 傳遞參數(shù)給線程函數(shù)

你可以通過 std::thread 構(gòu)造函數(shù)傳遞參數(shù)給線程函數(shù)。

#include <iostream>
#include <thread>
void printMessage(const std::string& message) {
    std::cout << message << "\\\\n";
}
int main() {
    std::thread t(printMessage, "Hello from thread!");
    t.join();
    std::cout << "Hello from main!\\\\n";
    return 0;
}

3. 線程同步

多個(gè)線程可能會(huì)同時(shí)訪問共享資源,導(dǎo)致數(shù)據(jù)競爭。為了避免這種情況,可以使用互斥鎖(std::mutex)來保護(hù)共享資源。

#include <iostream>
#include <thread>
#include <mutex>
#include <vector>
std::mutex mtx;  // 互斥鎖
void printNumber(int num) {
    mtx.lock();  // 加鎖
    std::cout << "Number: " << num << "\\\\n";
    mtx.unlock();  // 解鎖
}
int main() {
    std::vector<std::thread> threads;
    for (int i = 0; i < 10; ++i) {
        threads.emplace_back(printNumber, i);
    }
    for (auto& t : threads) {
        t.join();
    }
    return 0;
}

4. 使用 std::lock_guard 自動(dòng)管理鎖

std::lock_guard 是一個(gè) RAII 風(fēng)格的簡單的鎖管理器,它在構(gòu)造時(shí)自動(dòng)加鎖,在析構(gòu)時(shí)自動(dòng)解鎖。

#include <iostream>
#include <thread>
#include <mutex>
#include <vector>
std::mutex mtx;
void printNumber(int num) {
    std::lock_guard<std::mutex> lock(mtx);  // 自動(dòng)加鎖和解鎖
    std::cout << "Number: " << num << "\\\\n";
}
int main() {
    std::vector<std::thread> threads;
    for (int i = 0; i < 10; ++i) {
        threads.emplace_back(printNumber, i);
    }
    for (auto& t : threads) {
        t.join();
    }
    return 0;
}

5. 條件變量

條件變量(std::condition_variable)用于線程間的同步,允許一個(gè)線程等待另一個(gè)線程滿足某些條件。

配合std::condition_variable::wait() 函數(shù)的第一個(gè)參數(shù)的必須是比lock_guard更靈活控制也更復(fù)雜重度的鎖:std::unique_lock。它可以RAII自動(dòng)析構(gòu),也可以手動(dòng)lock/unlock,中間有的代碼段就可以釋放鎖。手動(dòng)把它unlock之后只是解鎖,沒有銷毀,后續(xù)可以按需復(fù)用再次 lock/unlock。

#include <iostream>
#include <thread>
#include <mutex>
#include <condition_variable>
std::mutex mtx;
std::condition_variable cv;
bool ready = false;
void printMessage() {
    std::**unique_lock**<std::mutex> lock(mtx);
    cv.wait(lock, []{ return ready; });  // 等待條件滿足
    std::cout << "Hello from thread!\\\\n";
}
int main() {
    std::thread t(printMessage);
    {
        std::lock_guard<std::mutex> lock(mtx);
        ready = true;  // 設(shè)置條件為 true
    }
    cv.notify_one();  // 通知等待的線程
    t.join();
    std::cout << "Hello from main!\\\\n";
    return 0;
}
相比lock_guard的優(yōu)勢:
1. 靈活性:unique_lock 支持延遲鎖定(可以先構(gòu)造對(duì)象而不立即加鎖),而 lock_guard 在構(gòu)造時(shí)就必須加鎖。這意味著你可以先創(chuàng)建 unique_lock 對(duì)象,然后根據(jù)程序邏輯需要時(shí)再調(diào)用 lock() 或 unlock() 方法進(jìn)行手動(dòng)加鎖或解鎖。
2. 條件變量的支持:unique_lock 可以與標(biāo)準(zhǔn)庫中的條件變量一起使用,如 std::condition_variable,這是 lock_guard 所不具備的功能。這是因?yàn)闂l件變量需要能夠原子地釋放鎖并進(jìn)入等待狀態(tài),這正是 unique_lock 提供的能力之一。
3. 鎖的所有權(quán)轉(zhuǎn)移:unique_lock 支持移動(dòng)語義(move semantics),允許將鎖的所有權(quán)從一個(gè) unique_lock 對(duì)象轉(zhuǎn)移到另一個(gè)對(duì)象,從而使得鎖可以在不同的作用域中傳遞。而 lock_guard 不支持這種操作,它的鎖所有權(quán)是固定的。
4. 嘗試鎖定(try-locking):除了基本的 lock() 和 unlock() 方法外,unique_lock 還提供了 try_lock() 方法,該方法嘗試獲取鎖但不會(huì)阻塞線程,如果無法獲得鎖則立即返回失敗結(jié)果。這對(duì)于避免線程長時(shí)間阻塞非常有用。
wait第二個(gè)參數(shù)predicate謂詞的用法參見:
<https://en.cppreference.com/w/cpp/thread/condition_variable/wait>
predicate不滿足不會(huì)結(jié)束等待執(zhí)行后續(xù)語句。

6. 線程池

C++ 標(biāo)準(zhǔn)庫沒有直接提供線程池的實(shí)現(xiàn),但你可以使用第三方庫(如 Boost)或自己實(shí)現(xiàn)一個(gè)簡單的線程池。

#include <iostream>
#include <thread>
#include <vector>
#include <queue>
#include <mutex>
#include <condition_variable>
#include <functional>
class ThreadPool {
public:
    ThreadPool(size_t numThreads) {
        for (size_t i = 0; i < numThreads; ++i) {
            workers.emplace_back([this] {
                while (true) {
                    std::function<void()> task;
                    {
                        std::unique_lock<std::mutex> lock(this->queueMutex);
                        this->condition.wait(lock, [this] { return this->stop || !this->tasks.empty(); });
                        if (this->stop && this->tasks.empty()) return;
                        task = std::move(this->tasks.front());
                        this->tasks.pop();
                    }
                    task();
                }
            });
        }
    }
    template<class F>
    void enqueue(F&& f) {
        {
            std::unique_lock<std::mutex> lock(queueMutex);
            tasks.emplace(std::forward<F>(f));
        }
        condition.notify_one();
    }
    ~ThreadPool() {
        {
            std::unique_lock<std::mutex> lock(queueMutex);
            stop = true;
        }
        condition.notify_all();
        for (std::thread &worker : workers) {
            worker.join();
        }
    }
private:
    std::vector<std::thread> workers;
    std::queue<std::function<void()>> tasks;
    std::mutex queueMutex;
    std::condition_variable condition;
    bool stop = false;
};
int main() {
    ThreadPool pool(4);
    for (int i = 0; i < 8; ++i) {
        pool.enqueue([i] {
            std::cout << "Task " << i << " is running on thread " << std::this_thread::get_id() << "\\\\n";
        });
    }
    return 0;
}

7. 線程局部存儲(chǔ)

線程局部存儲(chǔ)(Thread Local Storage, TLS)允許每個(gè)線程擁有自己的變量實(shí)例。C++11 引入了 thread_local 關(guān)鍵字來實(shí)現(xiàn)這一點(diǎn)。

#include <iostream>
#include <thread>
thread_local int threadLocalVar = 0;
void threadFunction(int id) {
    threadLocalVar = id;
    std::cout << "Thread " << id << " has threadLocalVar = " << threadLocalVar << "\\\\n";
}
int main() {
    std::thread t1(threadFunction, 1);
    std::thread t2(threadFunction, 2);
    t1.join();
    t2.join();
    return 0;
}

8. 異步任務(wù)

C++11 還引入了 std::async 和 std::future,用于異步執(zhí)行任務(wù)并獲取結(jié)果。

#include <iostream>
#include <future>
int compute() {
    std::this_thread::sleep_for(std::chrono::seconds(2));
    return 42;
}
int main() {
    // 啟動(dòng)異步任務(wù)
    std::future<int> fut = std::async(std::launch::async, compute);
    // 獲取結(jié)果
    int result = fut.get();
    std::cout << "Result: " << result << std::endl;
    return 0;
}
//使用 std::packaged_task (包在線程函數(shù)外)------------------------------------------
#include <iostream>
#include <future>
#include <thread>
int compute() {
    std::this_thread::sleep_for(std::chrono::seconds(2));
    return 42;
}
int main() {
    // 創(chuàng)建 packaged_task 
    std::packaged_task<int()> task(compute);
    // 獲取 future
    std::future<int> fut = task.get_future();
    // 在另一個(gè)線程中執(zhí)行任務(wù)
    std::thread t(std::move(task));
    t.join();
    // 獲取結(jié)果
    int result = fut.get();
    std::cout << "Result: " << result << std::endl;
    return 0;
}
// 使用 std::promise (作為線程函數(shù)參數(shù)) -----------------------------------------------
#include <iostream>
#include <future>
#include <thread>
void compute(std::promise<int> prom) {
    std::this_thread::sleep_for(std::chrono::seconds(2));
    prom.set_value(42);
}
int main() {
    // 創(chuàng)建 promise 和 future
    std::promise<int> prom;
    std::future<int> fut = prom.get_future();
    // 在另一個(gè)線程中執(zhí)行任務(wù)
    std::thread t(compute, std::move(prom));
    // 獲取結(jié)果
    int result = fut.get();
    std::cout << "Result: " << result << std::endl;
    t.join();
    return 0;
}

異步機(jī)制總結(jié): C++11 的異步機(jī)制(std::future、std::async、std::packaged_task 和 std::promise)相比傳統(tǒng)的多線程編程,提供了以下額外的好處:

更高的抽象層次,簡化了異步操作的管理。
自動(dòng)化的結(jié)果傳遞和異常處理。
更靈活的線程管理和任務(wù)執(zhí)行策略。
更清晰的代碼結(jié)構(gòu)和更低的耦合度。
支持任務(wù)組合和超時(shí)等待。

這些機(jī)制使異步編程更加直觀、安全和高效,是現(xiàn)代 C++ 并發(fā)編程的重要組成部分。

總結(jié)

C++ 多線程編程提供了強(qiáng)大的工具來處理并發(fā)任務(wù)。通過使用 std::threadstd::mutex、std::condition_variable 等工具,你可以編寫高效且安全的多線程程序。需要注意的是,多線程編程容易引入數(shù)據(jù)競爭和死鎖等問題,因此需要仔細(xì)設(shè)計(jì)和測試。

到此這篇關(guān)于c++ 標(biāo)準(zhǔn)庫多線程的文章就介紹到這了,更多相關(guān)c++ 標(biāo)準(zhǔn)庫多線程內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

  • 利用c++編寫簡易版2048小游戲

    利用c++編寫簡易版2048小游戲

    這篇文章主要介紹了如何讓利用c++編寫簡易版的2048小游戲,感興趣的小伙伴請(qǐng)參考下面文章的具體內(nèi)容
    2021-09-09
  • c++函數(shù)中的指針參數(shù)與地址參數(shù)區(qū)別介紹

    c++函數(shù)中的指針參數(shù)與地址參數(shù)區(qū)別介紹

    c++函數(shù)中的指針參數(shù)與地址參數(shù)區(qū)別介紹;可供參考
    2012-11-11
  • c語言B樹深入理解

    c語言B樹深入理解

    B樹是為磁盤或其他直接存儲(chǔ)設(shè)備設(shè)計(jì)的一種平衡查找樹,本文將詳細(xì)介紹c語言B樹,需要的朋友可以參考下
    2012-11-11
  • c++ class中成員與分配內(nèi)存的問題詳解

    c++ class中成員與分配內(nèi)存的問題詳解

    很多人都知道C++類是由結(jié)構(gòu)體發(fā)展得來的,所以他們的成員變量(C語言的結(jié)構(gòu)體只有成員變量)的內(nèi)存分配機(jī)制是一樣的,下面這篇文章主要給大家介紹了關(guān)于c++ class中成員與分配內(nèi)存問題的相關(guān)資料,需要的朋友可以參考下
    2021-10-10
  • 使用c++實(shí)現(xiàn)異或加密的代碼示例

    使用c++實(shí)現(xiàn)異或加密的代碼示例

    這篇文章主要為大家介紹了c++實(shí)現(xiàn)異或加密的代碼示例,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步早日升職加薪
    2022-04-04
  • 一起來了解c語言的str函數(shù)

    一起來了解c語言的str函數(shù)

    這篇文章主要為大家詳細(xì)介紹了c語言的str函數(shù),文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下,希望能夠給你帶來幫助
    2022-02-02
  • C++ 結(jié)構(gòu)體初始化與賦值詳解

    C++ 結(jié)構(gòu)體初始化與賦值詳解

    本文主要介紹了C++ 結(jié)構(gòu)體初始化與賦值詳解,文中通過示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2021-11-11
  • 詳解C語言快速排序三種方法的單趟實(shí)現(xiàn)

    詳解C語言快速排序三種方法的單趟實(shí)現(xiàn)

    本文將通過圖片重點(diǎn)為大家介紹一下C語言中快速排序三種方法的單趟實(shí)現(xiàn):分別是hoare法、挖坑法、雙指針法,文中示例代碼講解詳細(xì),感興趣的可以了解一下
    2022-06-06
  • C語言宏函數(shù)container of()簡介

    C語言宏函數(shù)container of()簡介

    這篇文章介紹了C語言宏函數(shù)container of(),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2021-12-12
  • Dashboard Interface 應(yīng)用實(shí)現(xiàn)操作

    Dashboard Interface 應(yīng)用實(shí)現(xiàn)操作

    Dashboard Server Remote Control Interface是一個(gè)關(guān)鍵的功能,它為用戶提供了通過TCP/IP協(xié)議遠(yuǎn)程控制機(jī)器人的能力,執(zhí)行包括開關(guān)機(jī)、加載程序、檢查機(jī)器人狀態(tài)以及設(shè)置機(jī)器人操作模式等多種操作,本文介紹Dashboard Interface 應(yīng)用操作,感興趣的朋友跟隨小編一起看看吧
    2024-08-08

最新評(píng)論