C++多线程应用
一个进程就是一个程序,一个程序里不止一个功能,每个功能的实现就可以交给一个线程去完成。一个进程就像是一个工程,这个工程里,有设计,有监理,有施工,就相当于三个线程,各干各的又相互配合。
https://cplusplus.com/reference/thread/thread/thread/
是C++的官方参考,个人觉得比较权威,比经过一些人去了解更好。每个人的思维方式不一样,直接看原始文档是最好的,何必吃别人嚼过的饭呢。
下面是我的心得,也算个参考吧。
一、创建一个线程大致有两种方法,一是先定义一个空线程,然后再实例化,二是直接实例化一个线程,直接干活。我个人倾向第二种,感觉第一种没什么意义。
二、对于join的理解。我的理解是:一个线程就是一个人,给这个人派任务后,有两种状态,一个是需要他回复,另一种是不需要。需要回复的,就用join,不需要回复的,就用detach。还拿设计,监理,施工,三人举例。施工前需要设计好才能开始施工,设计线程需要join,施工和监理是同时进行的,不能等施工完了,监理才检查,所以施工尤其不能join,只能detach,监理就可以马上开始了,监理作为最后一个工序可以join,也可以detach
三、joinable,就是表示这个线程的状态,一个线程,既有任务,又需要回复,就是joinable()== true,其余状态都是joinable()== false
四、当joinable()== true时,才对线程进行join或detach操作。否则不要进行这两种操作。即if(th.joinable()){th.join();或th.detach();}
五、std::hardware_concurrency()是CPU的核心数,按理说是一个核心对应一个线程。但是一个线程在执行完任务后就自动销毁了,CPU核心就空出来了。让线程等待新任务的话,也行,但我在实际运行过程中,会报错,也许是我学艺不精。我就简单粗暴,不断创建新线程。
六、线程池的概念我也不知道是谁发明的,就是先创建几个空线程,没事就等着,有事就干,干完也不消毁,继续等,说是能节约时间,我是觉得没什么用,而且官方参考里并没有这个说法。
上代码,用注释说明。
//此程序用多线程去调查学生的情况并记录。
#include <atomic> // 自锁型变量,防止多线程交叉操作,只能一个一个来,本例子并未使用,好像不支持string。
#include <thread> // 想用多线程,就要包含此包
#include <vector> // 使用多线程的辅助工具,任意类型的队列
#include <mutex> // 防止线程交叉操作同一代码用的,线程锁
mutex m; //定义一个线程锁
string a=“”; //用于记录的字符串
std::vector<std::thread> threaders;//创建一个线程队列,没有上限
//次子程序,用于获取学生的属性并记录,参数是学号,用很多线程执行这个子程序,一个线程调查一个学生,调查完不需要回复。这里假设,获取属性是个费时的工作,记录是个很快的动作,四个get_XXX()是预先写好的其他子程序。
void get_students_status(int student_number) //学号是学生的唯一标识
{
string name; //学生的姓名
string age; //学生的年龄
string height; //学生的身高
string weight; //学生的体重
name = get_name(student_number);
age = get_age(student_number);
height = get_height(student_number);
weight = get_weight(student_number);
//前面是调查的工作,可以多线程同步进行。后面是记录的工作,不能多线程同步进行,必须一个一个来,就需要加锁。这会让程序整体变慢,但没办法,记录是配套的,否则就乱了,比如名字后面应该是年龄,如果不加锁,可能会是另一个人的名字,
m.lock(); //加锁
a = a + name+": "+age +" "+height+" "+weight +"||";
m.unlock(); //解锁
}
main()
{
//对一万个学生进行调查并记录
for(int i = 1;i<10000;i++)
{
threaders.push_back(std::thread(get_students_status,i)); //针对每个学号创建一个线程,std::thread是创建线程的语句,其第一个参数是线程执行的子程序,第二个参数是该子程序的第一个参数,以此类推。threaders.push_back是把这个新创建的线程放在线程队列的队尾。
//遍历线程队列里的每个线程
for (auto& th : threaders)
{
if(th.joinable())th.detach();//如果此线程处于有任务,且需要回复的状态,就告诉他不用回复了。此处用join,就是等待其回复。那样就失去了多线程的意义,一个一个干,跟一个人干,没什么区别。
}
}
m.lock(); //加锁
cout<<a<<endl;//有可能还有线程没完成就输出了,可以想别的办法,比如前面加sleep(),或加锁。主线程也是线程啊。也可以在前面遍历线程那步,把最后一个线程join
m.unlock(); //解锁
}
C++多线程应用的更多相关文章
- Python中的多进程与多线程(一)
一.背景 最近在Azkaban的测试工作中,需要在测试环境下模拟线上的调度场景进行稳定性测试.故而重操python旧业,通过python编写脚本来构造类似线上的调度场景.在脚本编写过程中,碰到这样一个 ...
- 多线程爬坑之路-Thread和Runable源码解析之基本方法的运用实例
前面的文章:多线程爬坑之路-学习多线程需要来了解哪些东西?(concurrent并发包的数据结构和线程池,Locks锁,Atomic原子类) 多线程爬坑之路-Thread和Runable源码解析 前面 ...
- 多线程爬坑之路-学习多线程需要来了解哪些东西?(concurrent并发包的数据结构和线程池,Locks锁,Atomic原子类)
前言:刚学习了一段机器学习,最近需要重构一个java项目,又赶过来看java.大多是线程代码,没办法,那时候总觉得多线程是个很难的部分很少用到,所以一直没下决定去啃,那些年留下的坑,总是得自己跳进去填 ...
- Java多线程
一:进程与线程 概述:几乎任何的操作系统都支持运行多个任务,通常一个任务就是一个程序,而一个程序就是一个进程.当一个进程运行时,内部可能包括多个顺序执行流,每个顺序执行流就是一个线程. 进程:进程 ...
- .NET基础拾遗(5)多线程开发基础
Index : (1)类型语法.内存管理和垃圾回收基础 (2)面向对象的实现和异常的处理基础 (3)字符串.集合与流 (4)委托.事件.反射与特性 (5)多线程开发基础 (6)ADO.NET与数据库开 ...
- Java多线程基础——对象及变量并发访问
在开发多线程程序时,如果每个多线程处理的事情都不一样,每个线程都互不相关,这样开发的过程就非常轻松.但是很多时候,多线程程序是需要同时访问同一个对象,或者变量的.这样,一个对象同时被多个线程访问,会出 ...
- C#多线程之线程池篇3
在上一篇C#多线程之线程池篇2中,我们主要学习了线程池和并行度以及如何实现取消选项的相关知识.在这一篇中,我们主要学习如何使用等待句柄和超时.使用计时器和使用BackgroundWorker组件的相关 ...
- C#多线程之线程池篇2
在上一篇C#多线程之线程池篇1中,我们主要学习了如何在线程池中调用委托以及如何在线程池中执行异步操作,在这篇中,我们将学习线程池和并行度.实现取消选项的相关知识. 三.线程池和并行度 在这一小节中,我 ...
- C#多线程之线程池篇1
在C#多线程之线程池篇中,我们将学习多线程访问共享资源的一些通用的技术,我们将学习到以下知识点: 在线程池中调用委托 在线程池中执行异步操作 线程池和并行度 实现取消选项 使用等待句柄和超时 使用计时 ...
- C#多线程之线程同步篇3
在上一篇C#多线程之线程同步篇2中,我们主要学习了AutoResetEvent构造.ManualResetEventSlim构造和CountdownEvent构造,在这一篇中,我们将学习Barrier ...
随机推荐
- vue开发者工具dev-tool的安装
1.下载网址:https://github.com/Redxym/dev-tools 2.谷歌浏览器->扩展程序,拖动刚刚下载好的压缩包,将chrome文件夹添加至'加载已解压的扩展程序' // ...
- 为啥动态显示的名字就显示了undefined?
看不懂了昂,记录一下,慢慢理解吧 <!DOCTYPE html> <html> <head> <meta charset="utf-8"& ...
- [nRF24L01+] 5. 数据和控制接口
5. 数据和控制接口 5.1. 特点 管脚: IRQ(该信号为低电平有效信号,由三个可屏蔽中断源控制) CE(此信号为高电平,用于在RX或TX模式下激活芯片) CSN(SPI信号) SCK(SPI信号 ...
- 我当年如何入门Linux的?-zdc的那些往事
一.通信当年的疯狂 还记得09年初, 山寨机横行, 市场上手机主要还是塞班os, 小灵通还没有退出市场, 基于安卓的智能手机陆续推出. 没有王者荣耀,更没有微信, 小米的米聊还在ppt里: 那个时候网 ...
- Camera | 9.如何让camera支持闪光灯?-基于rk3568
一.闪光灯基本原理 工作模式 Camera flash led分flash和torch两种模式. flash: 拍照时上光灯瞬间亮一下,电流比较大,目前是1000mA,最大电流不能超过led最大承受能 ...
- ubuntu 16.04 安装Python3.8虚拟环境
virtualenv为应用提供了隔离的Python运行环境,可以解决不同应用间多版本的冲突问题. virtualenv会把用户指定版本的python复制到虚拟环境下,并修改相关的环境变量,使得pyth ...
- Java 读取 IP 地址
使用 InetAddress 类 可以利用 Java 自带的 InetAddress 类来检查一个字符串是否为有效的 IP 地址: import java.net.InetAddress; // 导入 ...
- 【测试平台开发】——01Vue前端框架实操
一.VScode官网地址 https://code.visualstudio.com/ 但是官网下载贼慢,需要修改下国内地址: 原地址:https://az764295.vo.msecnd.net/s ...
- 从数据洞察到智能决策:合合信息&infiniflow RAG技术的实战案例分享
从数据洞察到智能决策:合合信息&infiniflow RAG技术的实战案例分享 标题取自 LLamaIndex,这个内容最早提出于今年 2 月份 LlamaIndex 官方博客.从 22 年 ...
- CSS – Dimension min-content, max-content, fit-content
前言 无意间在 practice 的时候看到视频使用, 以前没有听过. 它有点像 Figma 的 hug content, 据说 CSS 2.1 也是有类似的概念, 只是没有被正式纳入 CSS 里. ...