C++ 教程 - 09 多线程处理

文章目录

  • thread标准库
  • 守护线性
  • pthread库

thread标准库

  • C++ 11 后添加了新的标准线程库 std::thread 类,
  • 需引入头文件<thread>
  • 支持windows,linux平台(linux平台下需要导入<pthread.h>,编译时并链入libpthread.so),可以利用多核cpu,并行执行,但是python的多线程却不可以利用多核心;
  • 声明变量并创建线程对象,如 thread th1; 调用无参构造,生成一个空的线程对象;
  • thread th(callable, args),传入调用函数及参数;
    • callable,可为函数;
    • callable,可为可调用对象;
    • callable,可为lambda 表达式(无名函数)
    • th.join() 等待当前子线程执行结束;
  • std::this_thread::sleep_for(chrono::seconds(1)) 线程内部延迟1s;
  • std::this_thread::get_id();
  • std::thread::harware_concurrency() 获取cpu核心数, 一般num + 1 个线程;
  • g++编译时,指定 -std=c++11 或者更新的版本;
#include <iostream>
#include <string>

// C++11后引入的 线程 标准库 std::thread 类  std::this_thread
#include <thread>
#include <chrono> // 延迟时间
using namespace std;



// 定义类
class People {
public:
	int age; // 实例 成员变量
	string name;

	People() {
		cout << "走无参构造函数..." << endl;
		this->age = 30;
	}
	People(const string& name, const int& age) {
		cout << "走有参构造函数..." << endl;
		this->name = name;
		this->age = age;
	}

	virtual ~People() {
		cout << "删除对象" << endl;
	}

	// 重载 函数调用()运算符,对象才可以调用
	void operator()(int age) {
		for (int i = 0; i < age; i++) {
			cout << "param age:" + to_string(age) << endl; // to_string 将int转为字符串,字符串支持 + 连接
			cout << "成员age:" << this->age << endl;

			// 延迟1s
			this_thread::sleep_for(chrono::seconds(1));
			cout << this_thread::get_id() << endl;
		}
		
	}
	
};


struct book { // 定义结构体,同C语法一致,只不过C++中可以单独使用book类声明变量,而C中必须使用struct book 声明
	char *title;
	double price;
};


// 函数
void myFunc(book arr[], int arrLen) {
	for (int i = 0; i < arrLen; i++) {
		cout << "当前书籍:" << endl;
		cout << arr[i].title << endl;
		cout << arr[i].price << endl;

		//std::this_thread 线程延迟1s
		this_thread::sleep_for(chrono::seconds(1));
		// 打印线程id
		cout << "线程id:" << this_thread::get_id() << endl; 
		cout << "" << endl;
	}
}


int main() {
	
	// 创建空子线程
	thread th1;
	
	// 创建子线程,并传参 '调用函数'、参数
	struct book arr[3]; // 数组分配内存,并创建结构体对象
	
	// 对象的指针属性,必须动态分配内存
	arr[0].title = new char(20);
	arr[0].title = (char*)"三国演义"; // 为对象赋值
	arr[0].price = 23.5;

	arr[1].title = new char(20);
	arr[1].title = (char*)"西游记";
	arr[1].price = 30.5;

	arr[2].title = new char(20);
	arr[2].title = (char*)"水浒传";
	arr[2].price = 28.5;

	thread th2(myFunc, arr, 3);

	// 创建子线程,并传参 lambda 表达式 (无名函数)
	auto exp1 = [](const int& num) { cout <<"lambda:" <<  num << endl; }; //  必须有 ; 号
	thread th3(exp1, 5);


	// 创建子线程,并传入 ‘可调用对象’、参数
	thread th4(People(), 20);


	// 等待子线程结束
	// th1.join(); // 空的子线程  不能.join()
	th2.join();
	th3.join();
	th4.join();

	return 0;
}

 

守护线性

  • 以上多线程的案例中,th.join() 等待子线程执行结束,会阻塞主线程;
  • th.detach() 设置为守护线程,后台运行,不影响主线程,但随着主线程的退出而退出;
  • 以下为linux案例;
#include <iostream>
#include <thread>
#include <chrono>
#include <pthread.h>
using namespace std;

void func(const int& a, const int& b){
    for(int i=0;i<100;i++){
    this_thread::sleep_for(chrono::seconds(1));
    cout << "sub thread running..." << endl;
    }

}

int main(){

  int a, b;
  a = 1;
  b = 2;
  thread th1(func, a, b);
  th1.detach(); // daemon thread

  cout << "main thread running..." << endl;
  // main thread
  this_thread::sleep_for(chrono::seconds(10));
  return 0;

}

 

pthread库

  • linux下使用pthread库创建子线程;
  • 需包含头文件<pthread.h>,且编译时链入libpthread.so动态库;
    • pthread_t 线程id类型;
    • pthread_create(&curThID, attr, funcName, void* args) 创建线程并执行,成功返回0,并将线程id存入curThID变量地址; attr线程对象的属性(可NULL); funcName为返回void* 且参数为void*的函数
    • 默认为守护线程,主线程结束时,不管子线程有没有结束,均都随主线程一起退出;
    • pthread_exit(NULL) ,在主线程中等待子线程执行结束;
    • pthread_attr_t 线程对象属性类型;
    • pthread_attr_init(&attr) 线程对象属性初始化;
    • pthread_attr_delete(attr) 线程对象属性删除;
    • pthread_join(thId, status) 连接线程,顺序执行;
    • pthread_detach() 分离线程;

 

在这里插入代码片

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

【MySQL】MySQL 9.0悄悄的来了

MySQL 9.0.0 中的变化 MySQL 9.0 中的新功能 JavaScript 存储程序 MySQL 企业版现在支持用 JavaScript 编写的存储程序&#xff0c;例如使用 CREATE FUNCTION下面显示的语句和 JavaScript 代码创建的这个简单示例&#xff1a; CREATE FUNCTION gcd(a INT, b INT) RETURNS …

SpringBoot-第一天学习

SpringBoot介绍-约定大于配置 SpringBoot是在Spring4.0基础上开发的&#xff0c;不是替代Spring的解决方案&#xff0c;而是和Spring框架结合并进一步简化Spring搭建和开发过程的。 如何简化&#xff1f;就是通过提供默认配置等方式让我们更容易&#xff0c;集成了大量常用的…

泛微开发修炼之旅--29用计划任务定时发送邮件提醒

文章链接&#xff1a;29用计划任务定时发送邮件提醒

嵌入式Linux系统编程 — 6.7 实时信号

目录 1 什么是实时信号 2 sigqueue函数 3 sigpending()函数 1 什么是实时信号 等待信号集只是一个掩码&#xff0c;它并不追踪信号的发生次数。这意味着&#xff0c;如果相同的信号在被阻塞的状态下多次产生&#xff0c;它只会在信号集中被记录一次&#xff0c;并且在信号集…

Django文档简化版——Django快速入门——创建一个基本的投票应用程序

Django快速入门——创建一个基本的投票应用程序 准备工作1、创建虚拟环境2、安装django 1、请求和响应&#xff08;1&#xff09;创建项目&#xff08;2&#xff09;用于开发的简易服务器&#xff08;3&#xff09;创建投票应用&#xff08;4&#xff09;编写第一个视图1、编写…

FreeRTOS的任务间通信

文章目录 4 FreeRTOS任务间通信4.1 队列4.1.1 队列的使用4.1.2 队列的创建&#xff0c;删除&#xff0c;复位4.1.3 队列的发送&#xff0c;接收&#xff0c;查询 4.2 邮箱&#xff08;mailbox&#xff09;4.2.1 任务中读写邮箱4.2.2 中断中读写邮箱 4.3 队列集4.3.1 队列集的创…

linux19:程序替换

一&#xff1a;最简单的看看程序替换是什么样的&#xff08;单个进程版&#xff09; 1 #include<stdio.h>2 #include<unistd.h>3 #include<stdlib.h>4 int main()5 {6 printf("Before : I am a process , myPid:%d,myPPid:%d\n",getpid(),getpp…

【Ubuntu】详细说说Parallels DeskTop安装和使用Ubuntu系统

希望文章能给到你启发和灵感~ 如果觉得文章对你有帮助的话,点赞 + 关注+ 收藏 支持一下博主吧~ 阅读指南 开篇说明一、基础环境说明1.1 硬件环境1.2 软件环境二、Ubuntu系统的使用2.1 系统的下载2.2 系统的安装2.3 安装桌面版(可选)2.3.1 安装/更新apt2.3.2 安装桌面版2.3…

算法day02 回文 罗马数字转整数

回文 搞错了String类型的indexOf方法&#xff0c;理解成获取对应下标的值&#xff0c;实际上是在找对应值的下标。 4ms 耗时最少的方法尽量不会去调用jdk提供的方法&#xff0c;而是直接使用对应的数学逻辑关系来处理&#xff0c; 甚至用 代替equals方法。 罗马数字转整数 考…

Simulink中示波器连续运行的方法

1.在Simulink中,经常要使用到示波器,默认示波器是定时运行的,只能观察到一小部分运行的波形;实际调试过程中,经常要连续运行,因此,需要设置示波器为连续运行模式,下面将介绍示波器连续运行的方法。 打开Simulink仿真软件,找到仿真设置按钮,点击设置: 2.将其停止时间…

Oracle 解决4031错误

一、问题描述 什么是4031错误和4031错误产生的原因: 简单一个句话概括: 由于服务器一直在执行大量的硬解析,导致Oracle 的shared pool Free空间碎片过多,大的chunk不足, 当又一条复杂的sql语句要硬解析时, 缺少1个足够大的Free chunk, 通常就会报4031错误. 二、解决方法 临…

JVM原理(十五):JVM虚拟机静态分配与动态分配

1. 分派 本节讲解的分派调用过程将会揭示多态性特征的一-些最基本的体现&#xff0c;如“重载”和“重写”在Java虚拟机之中是如何实现的。 1.1. 静态分派 案例&#xff1a; 我们先来看一段代码: Human mannew Man(); 我们把上面代码中的“Human"称为变量的“静态类型…

9 redis,memcached,nginx网络组件

课程目标: 1.网络模块要处理哪些事情 2.reactor是怎么处理这些事情的 3.reactor怎么封装 4.网络模块与业务逻辑的关系 5.怎么优化reactor? io函数 函数调用 都有两个作用:io检测 是否就绪 io操作 1. int clientfd = accept(listenfd, &addr, &len); 检测 全连接队列…

Contact Form 7表单获取提交用户IP及URL等信息

有时候&#xff0c;您可能需要了解Contact Form 7表单提交后的更多的信息&#xff0c;而不仅仅是通过联系人表单字段获取用户的联系信息。例如&#xff0c;需要知道用户是哪个国家&#xff08;通过获取IP&#xff09;&#xff0c;了解用户使用的设备&#xff08;手机还是电脑&a…

【IDEA】maven如何进行文件导入,配置并打包

一&#xff0c;介绍、安装 1、maven介绍 maven是一个Java世界中&#xff0c;构建工具。 核心功能&#xff1a; (1) 管理依赖&#xff1a; 管理文件运行的顺序逻辑依赖关系。对配置文件&#xff0c;进行构建和编译。其也是在调用jdk&#xff0c;来进行编译打包工作。 (2) 打…

Protobuf(三):理论学习,简单总结

1. Protocol Buffers概述 Protocol Buffers&#xff08;简称protobuf&#xff09;&#xff0c;是谷歌用于序列化结构化数据的一种语言独立、平台独立且可扩展的机制&#xff0c;类似XML&#xff0c;但比XML更小、更快、更简单protobuf的工作流程如图所示 1.1 protobuf的优点…

2024上海初中生古诗文大会暑期备考:单选题真题示例和独家解析

现在距离2024年初中生古诗文大会初选还有不到4个月&#xff08;11月3日正式开赛&#xff09;&#xff0c;我们继续来看10道选择题真题和详细解析。为帮助孩子自测和练习&#xff0c;题目的答案和解析统一附后。 本专题持续分享。 一、上海初中古诗文大会历年真题精选(参考答案…

【ROS2】初级:CLI工具- 启动节点

目标&#xff1a;使用命令行工具一次启动多个节点。 教程级别&#xff1a;初学者 时间&#xff1a;5 分钟 目录 背景 先决条件 任务 运行启动文件控制 Turtlesim 节点&#xff08;可选&#xff09; 摘要 下一步 背景 在大多数入门教程中&#xff0c;您每运行一个新节点就会打开…

【Unity配置数据文件】ScriptableObject核心应用

&#x1f468;‍&#x1f4bb;个人主页&#xff1a;元宇宙-秩沅 &#x1f468;‍&#x1f4bb; hallo 欢迎 点赞&#x1f44d; 收藏⭐ 留言&#x1f4dd; 加关注✅! &#x1f468;‍&#x1f4bb; 本文由 秩沅 原创 &#x1f468;‍&#x1f4bb; 专栏交流&#x1f9e7;&…

NASA——quarius(水瓶座) L3 网格化 1 度年土壤湿度,第 5 版

Aquarius L3 Gridded 1-Degree Annual Soil Moisture V005 水瓶座 L3 网格化 1 度年土壤湿度&#xff0c;第 5 版 简介 该数据集包含美国国家航空航天局&#xff08;NASA&#xff09;科学应用卫星&#xff08;SAC-D&#xff09;上的宝瓶座被动微波辐射计得出的第 3 级网格化…