当前位置: 首页 > news >正文

C++:线程库的使用

文章目录

  • Windows和Linux平台的线程
  • 线程
    • 构造函数
    • 模板参数包

最近发现C++11的线程库还没有进行总结,因此本篇对于C++11当中新增的线程库的一些基本用法进行总结

Windows和Linux平台的线程

在Linux平台下是存在一些原生的线程系统调用的,比如有pthread_create这样的系统调用,而在C++11标准之后,C++自己的标准库中也出现了有关线程的调用库,这样最大的好处就是只要使用的是C++提供的线程库,这样不管是在Linux下还是在Windows下都是可以使用的,提供了一个跨平台的好处,因为这本身是属于语言本身的

对于线程库当中的实现,其实就是把这样的类unix平台的接口和Windows的原生接口进行了一个条件编译,当检测到时WIN32的系统的时候,就使用的是Windows提供的原生的线程,而如果识别到时unix的系统,就使用unix提供的线程,具体可以理解为下面这样

#ifdef _WIN32
CreateThread()
#else
pthread_create()
#endif

线程

C++语言本身提供的这个线程,是一个用类进行封装的线程:

在这里插入图片描述
也提供了一些成员函数

在这里插入图片描述

构造函数

对于一个类来说,首先要看一下它的构造函数,看一下可以用什么样的方法来构造出这个函数

在这里插入图片描述
在上面的这四种构造函数中出现了一些熟悉的身影,默认构造函数是一个无参的构造函数,表示的是一个空线程,不启动,其次是一个模板,在这个模板中带有的是一个可变参数包,并且还有万能引用等,这些后续进行代码实践,需要注意的是其中的Fn表示的是一个可执行对象,可以是函数指针,仿函数,lambda表达式,包装器等等

从下面的拷贝函数可以看出,线程不支持拷贝构造,但是支持移动构造

模板参数包

为什么要诞生出这个模板参数包来进行构造函数?先看看Linux下的线程创建是怎么创建的

在这里插入图片描述
如图所示的是Linux下的线程创建的系统调用,第一个参数是线程的tid,这里就不多介绍了,重点是后面的函数指针,后面的arg表示的是函数指针的参数,那这就意味着会用到强转这样的信息来进行参数的解析,如果使用原生的方式要传递多个参数,通常要把这些信息放到一个结构体当中:

#include <iostream>
#include <unistd.h>
#include <string>
using namespace std;struct thread_data
{thread_data(const string &message, int id) : _message(message), _id(id) {}string _message;int _id;
};void *routine(void *arg)
{struct thread_data *td = (struct thread_data *)arg;cout << td->_message << " : " << td->_id << endl;return nullptr;
}int main()
{pthread_t tid;for (int i = 0; i < 5; i++){thread_data td("这是线程", i);pthread_create(&tid, nullptr, &routine, (void *)&td);pthread_join(tid, nullptr);}return 0;
}

而在C++11的库当中,如果使用这个模板参数包,就可以很方便的直接进行使用了:

#include <iostream>
#include <thread>
#include <windows.h>
#include <functional>
using namespace std;void func1(const string& message, int id)
{cout << message << " " << id << endl;
}struct func3
{void operator()(const string& message, int id){cout << message << " " << id << endl;}
};int main()
{// 使用函数指针string tmp1 = "这是函数指针的方法";int id1 = 1;thread t1(&func1, tmp1, id1);Sleep(1000);// 使用lambda表达式string tmp2 = "这是lambda的方法";int id2 = 2;thread t2([&](const string& message, int id) {cout << message << " " << id << endl;}, tmp2, id2);Sleep(1000);// 使用仿函数string tmp3 = "这是仿函数的方法";int id3 = 3;func3 f3;thread t3(f3, tmp3, id3);Sleep(1000);// 使用包装器function<void(const string&, int)> func4 = func1;string tmp4 = "这是包装器的方法";int id4 = 4;thread t4(func4, tmp4, id4);Sleep(1000);// 回收等待t1.join();t2.join();t3.join();t4.join();return 0;
}

如上所示是四种可执行方式调用线程的方式

http://www.lryc.cn/news/332343.html

相关文章:

  • 机器学习模型:决策树笔记
  • 20.2k stars项目搭建私人网盘界面美功能全
  • 卷积篇 | YOLOv8改进之引入全维度动态卷积ODConv | 即插即用
  • Pytorch实用教程:torch.from_numpy(X_train)和torch.from_numpy(X_train).float()的区别
  • 深度学习pytorch好用网站分享
  • C语言 | Leetcode C语言题解之第2题两数相加
  • Oracle基础
  • 从0到1实现RPC | 04 负载均衡和静态注册中心
  • 卷积神经网络-池化层
  • 【干货集】C# XmlHelper帮助类操作Xml文档的通用方法汇总
  • Coursera自然语言处理专项课程04:Natural Language Processing with Attention Models笔记 Week01
  • mysql MHA高可用
  • android 扫描二维码
  • [flink 实时流基础] 输出算子(Sink)
  • case语句
  • 全国加油站分布数据/停车场分布/公园分布/景区分布/保护区分布/poi感兴趣点
  • 单片机简介(一)
  • Naiveui将message挂载到axios拦截器
  • MySQL、Oracle查看字节和字符长度个数的函数
  • 第五篇:3.4 用户归因和受众(User attribution and audience) - IAB/MRC及《增强现实广告效果测量指南1.0》
  • ES6: class类
  • [中级]软考_软件设计_计算机组成与体系结构_08_输入输出技术
  • 2024-04-04 问AI: 在深度学习中,微调是什么?
  • db2数据仓库集群的搭建
  • Linux ARM平台开发系列讲解(u-boot篇) 5.1 u-boot的启动流程分析(ARMv8-a)
  • ST表(数据结构中的问题)
  • 一、OpenCV(C#版本)环境搭建
  • ubuntu远程服务部署,Docker,蓝牙无线局域网,SSH,VNC,xfce4,NextTerminal,宝塔,NPS/NPC,gost,openwrt
  • kettle安装与部署使用教程
  • 【C语言】编译和链接