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

C++多线程

时间:2023-05-27 11:34:21浏览次数:26  
标签:std include get lock C++ future 线程 多线程

多线程:

thread_local

每个线程都会有自己的一份数据,不会共享数据,避免竞争

 

volatile

告诉编译器每次取数据都要从内存里取

 

使用情况:

  1. 信号处理
  2. 内存映射相关
  3. 非本地跳转

 

std::atomic

定义操作为原子操作,不可被线程分开

 

接口

 

 

std::shread C++的线程类,但是不保证异步。std::async可以强制异步,可以指定两种异步方式:  std::launch::async(使用新的线程异步执行任务)和std::launch::deferred(用当前线程执行,时间上会延后)

 

如果需要在调用线程和新线程之间同步数据可以用promise和future

std::promise

其作用是在一个线程t1中保存一个类型typename T的值,可供相绑定的std::future对象在另一线程t2中获取。

 

std::future

可以用来获取异步任务的结果,因此可以把它当成一种简单的线程间同步的手段。std::future对象通常通过某个Provider创建,Provider在某个线程中设置共享状态的值,与该共享状态相关联的std::future对象通过get获得该值,如果该装填不为ready,则std::future::get会阻塞当前调用的人,知道Provider设置了共享状态的值为ready,get会返回异步任务的值或异常。

 

实例:

#include <iostream>

#include <future>

#include <chrono>

 

void Thread_Fun1(std::promise<int> &p)

{

//为了突出效果,可以使线程休眠5s

std::this_thread::sleep_for(std::chrono::seconds(5));

 

int iVal = 233;

std::cout << "传入数据(int):" << iVal << std::endl;

 

//传入数据iVal

p.set_value(iVal);

}

 

void Thread_Fun2(std::future<int> &f)

{

//阻塞函数,直到收到相关联的std::promise对象传入的数据

auto iVal = f.get(); //iVal = 233

 

std::cout << "收到数据(int):" << iVal << std::endl;

}

 

int main()

{

//声明一个std::promise对象pr1,其保存的值类型为int

std::promise<int> pr1;

//声明一个std::future对象fu1,并通过std::promise的get_future()函数与pr1绑定

std::future<int> fu1 = pr1.get_future();

 

//创建一个线程t1,将函数Thread_Fun1及对象pr1放在线程里面执行

std::thread t1(Thread_Fun1, std::ref(pr1));

//创建一个线程t2,将函数Thread_Fun2及对象fu1放在线程里面执行

std::thread t2(Thread_Fun2, std::ref(fu1));

 

//阻塞至线程结束

t1.join();

t2.join();

 

return 1;

}

 

C++20支持协程

 

std::mutex 互斥量,表示之后的代码段同时只能由一个线程访问

lock_guard是一种在作用域内可以控制可锁对象所有权的类型

特点:

(1) 创建即加锁,作用域结束自动析构并解锁,无需手工解锁
(2) 不能中途解锁,必须等作用域结束才解锁
(3) 不能复制

std::unique_lock 可以实现尝试获得锁, 如果当前以及被其它线程锁定, 则延迟直到其它线程释放, 然后才获得锁.

特点:

(1) 创建时可以不锁定(通过指定第二个参数为 std::defer_lock),而在需要时再锁定

(2) 可以随时加锁解锁

(3) 作用域规则同 lock_grard,析构时自动释放锁

(4) 不可复制,可移动

(5) 条件变量需要该类型的锁作为参数(此时必须使用 unique_lock)

 

std::mutex g_mutex;

std::lock_guard<std::mutex> guard(g_mutex);//可以及时进入和释放互斥量

实例:

#include <chrono>

#include <thread>

#include <mutex>

 

bool flag;

std::mutex m;

 

void wait_for_flag()

{

    std::unique_lock<std::mutex> lk(m); // 这里采用std::unique_lock而非std::lock_guard. std::unique_lock可以实现尝试获得锁, 如果当前以及被其它线程锁定, 则延迟直到其它线程释放, 然后才获得锁.

    while(!flag)

    {

        lk.unlock(); // 解锁互斥量

        std::this_thread::sleep_for(std::chrono::milliseconds(100));  // 休眠100ms,在此期间,其它线程可以进入互斥量,以便更改flag标记。

        lk.lock();   // 再锁互斥量

    }

}

 

 

std::condition_variable(条件变量)

 

源自博客:https://blog.csdn.net/qq_23350817/article/details/116460138

标签:std,include,get,lock,C++,future,线程,多线程
From: https://www.cnblogs.com/PireannUE/p/17436464.html

相关文章

  • 【模型部署 01】C++实现分类模型(以GoogLeNet为例)在OpenCV DNN、ONNXRuntime、TensorRT
    深度学习领域常用的基于CPU/GPU的推理方式有OpenCVDNN、ONNXRuntime、TensorRT以及OpenVINO。这几种方式的推理过程可以统一用下图来概述。整体可分为模型初始化部分和推理部分,后者包括步骤2-5。以GoogLeNet模型为例,测得几种推理方式在推理部分的耗时如下:结论:GPU加速首选Tens......
  • 1017 A除以B(C++)
    一、问题描述:本题要求计算 A/B,其中 A 是不超过1000位的正整数,B 是1位正整数。你需要输出商数 Q 和余数 R,使得 A=B×Q+R 成立。输入格式:输入在一行中依次给出 A 和 B,中间以1空格分隔。输出格式:在一行中依次输出 Q 和 R,中间以1空格分隔。输入样例:123......
  • C/C++飞机订票管理系统[2023-05-26]
    C/C++飞机订票管理系统[2023-05-26]题目5飞机订票管理系统设计1问题描述航空客运订票的业务包括:查询航班、客票预订和办理退票等。试设计一个航空客运订票系统,已使上述业务可以借助计算机完成。2.功能要求(1)每条航线所涉及的信息有:终点站名、航班号、飞机号、星期几飞......
  • c++打卡第三十八天
    一、歌星大奖赛1、问题描述 2、设计思路我们可以定义数组,存储十个评委所打的分数,输入十个数值,对这十个数值进行排序,然后去掉数组的首尾,计算的总和除以8计算得分数的平均数。3、流程图 4、代码实现#include<iostream>usingnamespacestd;intmain(){inta[10];......
  • 5.26 C++文件读写操作
    程序运行时产生的数据都属于临时数据,程序—旦运行结束都会被释放通过文件可以将数据持久化C++中对文件操作需要包含头文件<fstream>文件类型分为两种:1.文本文件:文件以文本的ASCII码形式存储在计算机中2.二进制文件:文件以文本的二进制形式存储在计算机中操作文件的三大类:ofst......
  • C++
    运算符重载#include<iostream>usingnamespacestd;classTime{public:Time(){}Time(inth,intm){hour=h;minute=m;}friendTimeoperator-(Time&a,Time&b){Timec;if(a.minute>b.minute&&am......
  • 使用 OpenCV 进行轮廓检测 (Python/C++)第一部分
    什么是轮廓当我们连接一个对象边界上的所有点时,我们得到一个轮廓。通常,特定轮廓是指具有相同颜色和强度的边界像素。OpenCV使得在图像中查找和绘制轮廓变得非常容易。它提供了两个简单的功能:findContours()drawContours()此外,它有两种不同的轮廓检测算法:CHAIN_APPROX_SIMPLECHAIN_......
  • C++类的基础、构造、析构
    双向链表节点——具体的表表里面要维护什么是由你自己来决定的以链表为例讲解为什么需要类用户修改了你的链表,暴露给所有人创建和销毁,忘记了,内存泄漏冗长的名字封装分离实现细节和接口一定要把细节private接口public接口修改调用我们是知道的......
  • c++打卡练习(40)(大一最后一次)
    求可逆素数若一个四位数的素数把它倒序过来还是素数,那么称它为可逆素数,如1009和9001就是一对可逆素数流程图:伪代码:源代码:#include<iostream>usingnamespacestd;intmain(){ intstart,end,i,j,m=0; for(i=1000;i<=9999;i++){ intk=0; for(j=2;j<i;j++){ if(i%j==0){ ......
  • Java大文件分片上传/多线程上传方案
    ​ 在Web应用系统开发中,文件上传和下载功能是非常常用的功能,今天来讲一下JavaWeb中的文件上传和下载功能的实现。先说下要求:PC端全平台支持,要求支持Windows,Mac,Linux支持所有浏览器。支持文件批量上传支持文件夹上传,且要求在服务端保留层级结构。文件夹数量要求支持到10W......