C++ 多线程编程和线程池

c++ 多线程需要包含thread头文件

#include <thread>std::thread t(function_name, args...);

多线程调用函数代码如下

#include <iostream>
#include <thread>
void print_message() 
{    std::cout << "Hello, world!" << std::endl;
}
int main() 
{    std::thread t(print_message);    t.join();return 0;
}

子线程和主线程同时执行,当子线程没执行完,主线程结束时,程序就会报错

join,主线程等待子线程执行完成后再执行,只能使用一次
detach,主程序结束,子线程会在后台执行
joinable,判断线程是否可以调用join和detach

//当子线程没有执行完时,主线程会阻塞在join()位置
bool isJoin = thread.joinable()
if(isJoin)
{thread.join()// 让主线程等待子线程
}

note:
1、右值传递给左值引用会报错可以使用std::ref ,右值引用
2、多线程中传递的指针可能存在被释放的问题需要注意
3、线程安全,多线程的运行程序和单线程的运行结果都是一样的

实现线程安全可以使用互斥锁、信号量、条件变量等操作

//互斥锁
std::mutex mtx;
mtx.lock();
//...
mtx.unlock();

lock_gurad,只在局部作用域中使用,不能复制和移动,轻量级锁
unqiue_lock,重量级锁,可以手动加锁、延迟加锁

手写实现一个线程池

#include <iostream>
#include <thread>
#include <mutex>
#include <string>
#include <queue>
#include <vector>
#include <functional>
#include <condition_variable>class ThreadPool {
public:ThreadPool(int numTread) : stop(false){for (int i = 0; i < numTread; i++){threads.emplace_back([this]{while (1){std::unique_lock<std::mutex> lock(mtx);condition.wait(lock, [this]{return !tasks.empty() || stop;});if (stop && tasks.empty()){return;}std::function<void()> task(std::move(tasks.front()));tasks.pop();lock.unlock();task();}});}}~ThreadPool(){{std::unique_lock<std::mutex> lock(mtx);stop = true;}condition.notify_all();for (auto& t : threads){t.join();}}template<class F,class ... Args>void enqueue(F&& f, Args&& ... args){std::function<void()> task =std::bind(std::forward<F>(f), std::forward<Args>(args)...);{std::unique_lock<std::mutex> lock(mtx);tasks.emplace(std::move(task));}condition.notify_one();}
private:bool stop;std::condition_variable condition;std::mutex mtx;std::vector < std::thread > threads;std::queue < std::function<void()>> tasks;
};
int main()
{// 创建一个线程池,里面包含4个线程ThreadPool pool(4);// 4个线程执行10个任务for (int i = 0; i < 10; i++){// 往线程池里加任务pool.enqueue([i](){std::cout << "task : " << i << " is runing " << std::endl;std::this_thread::sleep_for(std::chrono::seconds(1));std::cout << "task : " << i << " is done " << std::endl;});}return 0;
}

参考资料
1、http://www.seestudy.cn/?list_9/31.html

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/622204.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

Dubbo 3.x结合Zookeeper实现远程服务基本调用

ZooKeeper和Dubbo是两个在分布式系统中常用的开源框架&#xff0c;它们可以协同工作&#xff0c;提供服务注册与发现、分布式协调等功能。 - 服务注册与发现&#xff1a; Dubbo服务提供者将自己的信息&#xff08;如IP地址、端口、服务名等&#xff09;注册到ZooKeeper上&…

乐意购项目前端开发 #2

一、Axios的安装和简单封装 安装Axios npm install axios在utils目录下创建 http.js 文件, 内容如下 import axios from axios// 创建axios实例 const http axios.create({baseURL: http://localhost:9999,//后端服务器地址timeout: 5000 })// axios请求拦截器 http.interc…

为什么使用双token实现无感刷新用户认证?

单token机制 认证机制&#xff1a;对与单token的认证机制在我们项目中仅使用一个Access Token的访问令牌进行用户身份认证和授权的方案处理。 不足之处&#xff1a; 安全性较低&#xff08;因为只有一个token在客户端和服务器端之间进行传递&#xff0c;一旦Access Token被截…

ZZULIOJ 1116: 删除元素

题目描述 输入一个递增有序的整型数组A有n个元素&#xff0c;删除下标为i的元素&#xff0c;使其仍保持连续有序。注意&#xff0c;有效下标从0开始。 定义如下两个函数分别实现删除元素操作和数组输出操作。 void del(int a[], int n, int i); /*删除数组a中下标为i的元素*/…

pip查看某个包存在的历史版本

简介&#xff1a;当我们想查看某个包有哪些可安装版本&#xff0c;但是又不想去官网查询&#xff0c;如何用pip命令查询出全部历史版本&#xff1f; 历史版本&#xff1a; Python&#xff1a;pip升级超时解决方案 Python&#xff1a;指定的Python版本pip Python&#xff1a…

鸿蒙开发-UI-布局

鸿蒙开发-序言 鸿蒙开发-工具 鸿蒙开发-初体验 鸿蒙开发-运行机制 鸿蒙开发-运行机制-Stage模型 鸿蒙开发-UI 鸿蒙开发-UI-组件 鸿蒙开发-UI-组件-状态管理 鸿蒙开发-UI-应用-状态管理 鸿蒙开发-UI-渲染控制 文章目录 前言 一、布局概述 1.布局结构 2.布局元素组成 3.布局分类 …

TRB 2024论文分享:基于生成对抗网络和Transformer模型的交通事件检测混合模型

TRB&#xff08;Transportation Research Board&#xff0c;美国交通研究委员会&#xff0c;简称TRB&#xff09;会议是交通研究领域知名度最高学术会议之一&#xff0c;近年来的参会人数已经超过了2万名&#xff0c;是参与人数和国家最多的学术盛会。TRB会议几乎涵盖了交通领域…

三、ngxin虚拟主机

目录 什么是nginx虚拟主机修改端口 访问页面1、配置nginx.config 文件2、 添加配置给目录中写入内容检测nginx 是否有语法错误&#xff08;nginx -t&#xff09;重启 nginx查看配置结果 不同主机网卡 查看到不同的页面先添加一个临时ip修改ngixn配置文件创建目录文件检测nginx …

在vue项目中使用百度地图,点击或搜索打点组件封装

一、在index.html文件中引入百度地图 <!DOCTYPE html> <html lang"en"> <head><meta charset"UTF-8"><meta http-equiv"X-UA-Compatible" content"IEedge"><meta name"viewport" content…

React入门 - 06(TodoList 列表数据的新增和删除)

本章内容 目录 一、实践一下 React 的列表渲染二、TodoList 新增功能三、列表循环的 key四、删除 上一节内容我们完成了输入框中可以自由输入内容&#xff0c;这一节我们继续 TodoList功能的完善&#xff1a;列表数据的新增和删除。 在开始之前&#xff0c;我们先介绍一下 Re…

前端对接电子秤、扫码枪设备serialPort 串口使用教程

因为最近工作项目中用到了电子秤&#xff0c;需要对接电子秤设备。以前也没有对接过这种设备&#xff0c;当时也是一脸懵逼&#xff0c;脑袋空空。后来就去网上搜了一下前端怎么对接&#xff0c;然后就发现了SerialPort串口。 Serialport 官网地址&#xff1a;https://serialpo…

c++八股1

对多态的认识&#xff1a; 在C中&#xff0c;多态性是面向对象程序设计的一个核心特性&#xff0c;它体现了“一个接口&#xff0c;多种实现”的思想。多态有两种形式&#xff1a; 静态多态&#xff08;编译时多态&#xff09;&#xff1a;通过函数重载和运算符重载实现&#x…

Linux 内核学习 3 - 虚拟内存和物理内存

虚拟内存其实是 CPU 和操作系统使用的一个障眼法&#xff0c;联手给进程编织了一个假象&#xff0c;让进程误以为自己独占了全部的内存空间&#xff1a; 在 32 位系统中&#xff0c;进程以为自己独占了 3G 的内存空间。 在 64 位系统中&#xff0c;进程以为自己独占了 128T 的…

NodeJs 第十二章 nodemon

nodemon 是一个监视器&#xff0c;用于监控工程中的文件变化&#xff0c;如果发现文件有变化&#xff0c;可以执行一段脚本。 本章节只介绍基础用法&#xff0c;深入学习请参考 官方文档 安装 全局安装 npm install -g nodemon本地安装 npm install --save-dev nodemon用法 …

杨中科 EFCORE 第四部分 命令详解56-61

Migrations 深入研究Migrations 1、使用迁移脚本&#xff0c;可以对当前连接的数据库执行编号更高的迁移&#xff0c;这个操作叫做“向上迁移” (Up)&#xff0c;也可以执行把数据库回退到旧的迁移&#xff0c;这个操作叫“向下迁移(Down&#xff09; 2、除非有特殊需要&…

机器人行业概况(2)

上篇已经介绍过关于机器人的定义以及分类&#xff0c;下面来看看机器人产业市场规模。 二、国内机器人产业市场规模 中国机器人产业在国家智能制造相关政策的引导下蓬勃发展。在新冠肺炎疫情防控期间&#xff0c;消毒、配送、测温、巡检等各类机器人的“火线上岗”&#xff0…

javascript:javascript去除字符串空格(空白符)

使用js去除字符串内所带有空格&#xff0c;有以下三种方法&#xff1a; 1 replace正则匹配方法 去除字符串内所有的空格 str str.replace(/\s*/g,""); 去除字符串内两头的空格 str str.replace(/^\s*|\s*$/g,""); 去除字符串内左侧的空格 str st…

spring-boot2.7.8添加swagger

一、新建项目swaggerdemo 二、修改pom.xml 注意修改&#xff1a;spring-boot-starter-parent版本为&#xff1a;2.7.8 添加依赖&#xff1a; springfox-swagger2 springfox-swagger-ui springfox-boot-starter <?xml version"1.0" encoding"UTF-8"…

C++日志库——spdlog

介绍 https://github.com/gabime/spdlog.git spdlog is a header only library. Just copy the files under include to your build tree and use a C11 compiler. spdlog是一个仅有头文件的库&#xff0c;只需要拷贝include下面的文件加到本地工程目录并使用支持C11的编译器编…

【打卡】牛客网:BM86 大数加法

题目分析&#xff1a; 因为是大数&#xff0c;所以不能&#xff1a;将string转为int&#xff0c;进行相加后&#xff0c;再int转为string。 而是直接模拟加法过程。 我写的&#xff1a; 一些细节&#xff1a; 需要反转。因为字符串从左到右遍历&#xff0c;加法从右往左遍…