首页 > 编程语言 >c++ 多线程

c++ 多线程

时间:2023-12-12 20:01:58浏览次数:29  
标签:std c++ future promise C++ 线程 多线程

https://blog.csdn.net/sjc_0910/article/details/118861539

unique_lock 和 lock_guard

多线程是一种实现并发处理的有效方式,C++11开始引入了<thread>库,使得多线程编程更加容易和高效。以下是C++中多线程编程的一些主要内容:

  1. 线程的创建:在C++中,可以使用std::thread类来创建一个新的线程。例如:

    #include <iostream>
    #include <thread>
    
    void function_1() {
        std::cout << "Hello, World!" << std::endl;
    }
    
    int main() {
        std::thread thread_1(function_1);  // 创建一个新的线程
        thread_1.join();  // 等待线程结束
        return 0;
    }
    
  2. 线程同步:当多个线程需要访问共享数据时,就需要进行线程同步以避免数据竞争。C++提供了多种同步机制,如std::mutexstd::lock_guardstd::unique_lock等。

  3. 数据传递:可以使用std::asyncstd::futurestd::promise等机制在线程之间传递数据。

  4. 异常处理:如果线程函数抛出一个未捕获的异常,std::terminate会被调用,这将导致程序的异常终止。为了避免这种情况,可以在线程函数中使用try/catch块来捕获和处理异常。

在C++多线程编程中,数据传递是一个重要的问题。以下是一些常见的数据传递方式:

  1. 通过函数参数传递:当创建一个新的线程时,可以通过函数参数将数据传递给线程函数。例如:

    void thread_function(int x) {
        // 在这里使用x
    }
    
    int main() {
        int data = 42;
        std::thread t(thread_function, data);
        t.join();
        return 0;
    }
    

    在这个例子中,我们将data作为参数传递给了thread_function

  2. 通过全局变量传递:所有线程都可以访问全局变量,因此全局变量可以用于在线程之间传递数据。但是,需要注意的是,如果多个线程同时访问和修改全局变量,可能会导致数据竞争。

  3. 通过std::promisestd::future传递std::promisestd::future是C++11引入的两个类,可以用于在线程之间传递数据4。你可以在一个线程中设置std::promise的值,然后在另一个线程中获取这个值4

  4. 通过std::async传递std::async是一个函数模板,可以用于创建一个异步任务,并返回一个std::future对象5。这个std::future对象可以用于获取异步任务的结果5

  5. 通过std::mutexstd::lock_guard进行同步:在多线程编程中,当多个线程需要访问共享数据时,就需要进行线程同步以避免数据竞争2。C++提供了多种同步机制,如std::mutexstd::lock_guardstd::unique_lock2

std::promisestd::future是C++11引入的两个类,它们提供了一种在不同线程之间传递数据的机制。

  • std::promisestd::promise对象可以保存某一类型T的值,该值可被std::future对象读取(可能在另外一个线程中),因此std::promise提供了一种线程同步的手段。在std::promise对象构造时可以和一个共享状态(通常是std::future)相关联,并可以在相关联的共享状态上保存一个类型为T的值。std::promise对象是异步Provider,它可以在某一时刻设置共享状态的值。

  • std::futurestd::future对象可以异步返回共享状态的值,或者在必要的情况下阻塞调用者并等待共享状态标志变为ready,然后才能获取共享状态的值。

以下是一个使用std::promisestd::future的C++示例1

#include <iostream>
#include <thread>
#include <future>

void print_int(std::future<int>& fut) {
    int x = fut.get();  // 获取共享状态的值.
    std::cout << "value: " << x << '\n';  // 打印 value: 10.
}

int main() {
    std::promise<int> prom;  // 生成一个 std::promise<int> 对象.
    std::future<int> fut = prom.get_future();  // 和 future 关联.
    std::thread t(print_int, std::ref(fut));  // 将 future 交给另外一个线程t.
    prom.set_value(10);  // 设置共享状态的值, 此处和线程t保持同步.
    t.join();
    return 0;
}

在这个示例中,我们首先创建了一个std::promise对象和一个std::future对象,然后在一个新的线程中使用std::future对象来获取std::promise对象设置的值。

 

 

 

   

标签:std,c++,future,promise,C++,线程,多线程
From: https://www.cnblogs.com/whcjob/p/17897672.html

相关文章

  • 笔记:Qt开发之多线程的实现(QThread、moveToThread)
    目标:了解Qt实现多线程的两种基本方式(QThread、moveToThread),各自的实现方式、使用场景。1,子类化QThread实现方式:继承QThread类,重写run()函数实现多线程classWorkerThread:publicQThread{ Q_OBJECT public: explicitMyThread(QObject*parent=nullptr):QObject(pare......
  • 使用C++和QT实现Log自定义日志系统
    MyLog说明使用QT的qInstallMessageHandler函数结合qDebug,qInfo实现自定义的日志系统输出日志到文件和控制台自动检测日志文件大小自动更新日志文件修改日期自动备份自动删除一个月前的日志文件支持多线程程序支持扩展,可输出日志到数据库,网络,或服务器支持扩展,可使用co......
  • 关于c++序列化
    对于一个复杂数据对象的存储和装载有很多方式,比如自定义的文本或者2进制格式,以及对应的读取和写入程序。也有一些适应力较强比较通用的方式,文本的有xml和json。尤其是xml文件查看起来比较方便。但是xml的最大问题就是装载和保存都比较慢。装载1个大文件足以把头发等白:)在c++里......
  • C++学习笔记八:极限和数学运算<limits><cmath>
    1)<limits>库:1.1源文档:https://en.cppreference.com/w/cpp/types/numeric_limits#include<limits> 1.2库函数:函数解释:对于一个浮点数,lowest表示最小的可表示的负数,min表示最小的可表示的接近0的数,max表示最大的可表示的正数对于一个有符号整数,min表示可以表示的最小的......
  • 12.12邻接表存储实现图的深度优先遍历(c++)
    今天学习了数据结构中的邻接表存储实现图的深度优先遍历,其中让我受益匪浅,以下是我的解题思路。编写程序,实现由邻接表存储实现无向图的深度优先搜索遍历的功能。顶点为字符型。输入格式:第一行输入顶点个数及边的个数,第二行依次输入各顶点,第三行开始依次输入边的两个顶点,用空格......
  • 12.11 迪杰斯特拉方法实现最短路径(c++)
     今天通过自主学习,,对数据结构中的迪杰斯特拉方法实现最短路径进行了深造,让我学会了很多新的东西。首先是问题描述:用迪杰斯特拉算法实现有向网的最短路径输入格式:第一行输入有向网的顶点和边数,第二行输入各顶点值,用空格间隔,第三行开始输入各条边的两个点的及边上的权值,用空......
  • C++ Qt开发:SpinBox数值微调框组件
    Qt是一个跨平台C++图形界面开发库,利用Qt可以快速开发跨平台窗体应用程序,在Qt中我们可以通过拖拽的方式将不同组件放到指定的位置,实现图形化开发极大的方便了开发效率,本章将重点介绍QSpinBox精度数值组件的常用方法及灵活运用。QSpinBox是Qt框架中的一个部件(Widget),用于提供一个方......
  • 学习C++算法入门第二天
    头文件#include<iostream> i=input,o=outputusingnamespacestd;头文件函数:https://blog.csdn.net/qq_32699009/article/details/104615792参考这个HelloWorld!---C学过,第一次接触C++,开启新的语言学习cin>>输入;cout<<输出<<endl; 啥是闰年?---非整百年:能被4整除的为闰......
  • C++语言string、wstring、utf-8互转
    实现了一个CStrCvt类,采用STL实现,可跨平台。注意的是,在s2ws和ws2s函数中需要locale信息,在使用过程中,需要根据实际情况进行设置。如果有需要可以检测文本编码,网上有开源的第三方库,可供使用。不过,准确率需自己判断。为了不影响效率,此类默认按照中文处理。头文件classCStrCvt{pu......
  • 算法战斗第一天C++1
    A.Watermelon西瓜(timelimitpertest:1second,memorylimitpertest:64megabytes,input:standardinput,output:standardoutput)OnehotsummerdayPeteandhisfriendBillydecidedtobuyawatermelon.Theychosethebiggestandtheripest熟one,int......