C++并发编程线程间共享数据std::future和sd::promise
線程間共享數據
同步并發操作
C++標準庫提供了一些工具 可以用于同步操作,形式上表現為條件變量(condition variables)和期望(futures)
C++標準中有兩套實現std::condition_variable和std::condition_variable_any這兩個實現都包含在<condition_variable>頭文件中,前者只能std::mutex一起工作,后者可以和任何滿足最低標準的互斥量一起工作,從而后者加上了_any后綴
條件變量使用示例
#include <iostream> #include <mutex> #include <condition_variable> #include <queue>typedef int32_t data_chunk;std::mutex mut; std::queue<data_chunk> data_queue; // 1 std::condition_variable data_cond; void data_preparation_thread() {while(more_data_to_prepare()){data_chunk const data=prepare_data();std::lock_guard<std::mutex> lk(mut);data_queue.push(data); // 2// 對等待線程進行通知data_cond.notify_one(); // 3} }void data_processing_thread() {while(true){std::unique_lock<std::mutex> lk(mut); // 4data_cond.wait(lk,[]{return !data_queue.empty();}); // 5data_chunk data=data_queue.front();data_queue.pop();lk.unlock(); // 6process(data);if(is_last_chunk(data))break;} }只執行一次的等待事件future
當一個事件只需要等待條件變量為true之后就不需要再次等待了可以使用futrure(期望)。
在C++中有兩種期望實現,使用兩種類型模板實現,聲明在頭文件中:唯一unique_futures(std::future<>)和共享shared futures(std::shared_future<>)
#include <future> #include <iostream> #include <thread>int find_the_answer_to_ltuae() {return 3; } void do_other_stuff() {std::this_thread::sleep_for(std::chrono::seconds(6)); }int main(int argc, char *argv[]) {// 默認在新線程上執行std::future<int>the_answer=std::async(find_the_answer_to_ltuae);do_other_stuff();std::cout<<"The answer is "<<the_answer.get()<<std::endl;return 0; }上述代碼一旦創建future對象就會調用傳入的函數,要是想函數延遲執行可以使用dferred標志實現,加上std::launch::deferred之后,只有在調用get或者wait的時候才會執行函數,使用方式如下:
#include <future> #include <iostream> #include <thread>using namespace std;int find_the_answer_to_ltuae() {cout << "find the answer." << endl;return 3; } void do_other_stuff() {std::this_thread::sleep_for(std::chrono::seconds(6));cout << "do other stuff " << endl; }int main(int argc, char *argv[]) {// 在調用get 或者wait的時候執行std::future<int>the_answer=std::async(std::launch::deferred, find_the_answer_to_ltuae);do_other_stuff();std::cout<<"The answer is "<<the_answer.get()<<std::endl;return 0; }std::promise 是C++11并發編程中常用到的一個類,常配合std::future使用。其作用是在一個線程t1中保存一個類型T的值,可供相綁定的std::future對象在另一線程t2中獲取。
std::promise會設置一個類型為T的和std::future關聯起來的對象。可以通過get_future獲取。
// // Created by Achou.Wang on 2021/8/31. // #include <iostream> #include <string> #include <future> #include <chrono>/** std::promise<int> 多線程之間共享數據* */void WorkThread1(std::promise<std::string> &p) {// 等待一會使得效果更加明顯std::this_thread::sleep_for(std::chrono::seconds(3));// 傳入數據std::string name("promise test.");std::cout << "promise set : " << name << std::endl;// 將數據傳入/*Stores the value into the shared state without making the state ready immediately.* The state is made ready when the current thread exits, after all variables* with thread-local storage duration have been destroyed.*/// 只要在線程退出,當前線程中的局部變量一類的都清理完全之后才會設置值,通常用于管理線程中獲取線程的狀態 // p.set_value_at_thread_exit(name);p.set_value(name);std::this_thread::sleep_for(std::chrono::seconds(6)); }void WorkThread2(std::future<std::string> &fu) {// 使用get獲取值,該函數是個阻塞的函數,直到對方設置之后才會解開阻塞std::cout << "begin get future data " << std::endl;auto name = fu.get();std::cout << "get name : " << name << std::endl; }int main() {// 先聲明promisestd::promise<std::string> p1;// 聲明一個future 引用promise的futurestd::future<std::string> fu = p1.get_future();//創建一個線程t1,將函數Thread_Fun1及對象pr1放在線程里面執行std::thread t1(WorkThread1, std::ref(p1));//創建一個線程t2,將函數Thread_Fun2及對象fu1放在線程里面執行std::thread t2(WorkThread2, std::ref(fu));//阻塞至線程結束t1.join();t2.join();return 0; }飛書文檔鏈接: https://ny5odfilnr.feishu.cn/docs/doccnnvMCH7nPKidScKSnJmiJie
有需要源碼或者一起學習C++的可以關注公眾號:
總結
以上是生活随笔為你收集整理的C++并发编程线程间共享数据std::future和sd::promise的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 使用go语言GUI库实现对mp3文件的播
- 下一篇: 作者:王融,中国信息通信研究院互联网法律