C++线程的简单学习及了解

此篇文章只是线程的简单了解。

文章目录

  • 前言
  • 一、线程的优缺点
  • 二、C++线程库
    • 1.thread类的简单介绍
    • 2.线程函数参数
  • 总结


前言

什么是线程?

在一个程序里的一个执行路线就叫做线程(thread)。更准确的定义是:线程是“一个进程内部的控制序列”
一切进程至少都有一个执行线程
线程在进程内部运行,本质是在进程地址空间内运行
透过进程虚拟地址空间,可以看到进程的大部分资源,将进程资源合理分配给每个执行流,就形成了线程执行流

一、线程的优缺点

1.线程的优点:

创建一个新线程的代价要比创建一个新进程小得多
与进程之间的切换相比,线程之间的切换需要操作系统做的工作要少很多
线程占用的资源要比进程少很多
能充分利用多处理器的可并行数量
在等待慢速I/O操作结束的同时,程序可执行其他的计算任务
计算密集型应用,为了能在多处理器系统上运行,将计算分解到多个线程中实现
I/O密集型应用,为了提高性能,将I/O操作重叠。线程可以同时等待不同的I/O操作。
2.线程的缺点
性能损失:一个很少被外部事件阻塞的计算密集型线程往往无法与共它线程共享同一个处理器。如果计算密集型线程的数量比可用的处理器多,那么可能会有较大的性能损失,这里的性能损失指的是增加了额外的同步和调度开销,而可用的资源不变。
健壮性降低:编写多线程需要更全面更深入的考虑,在一个多线程程序里,因时间分配上的细微偏差或者因共享了不该共享的变量而造成不良影响的可能性是很大的,换句话说线程之间是缺乏保护的。
缺乏访问控制:进程是访问控制的基本粒度,在一个线程中调用某些OS函数会对整个进程造响。
编程难度提高:编写与调试一个多线程程序比单线程程序困难得多
3.线程异常
单个线程如果出现除零,野指针问题导致线程崩溃,进程也会随着崩溃。
线程是进程的执行分支,线程出异常,就类似进程出异常,进而触发信号机制,终止进程,进程终止,该进程内的所有线程也就随即退出。
4.线程用途
合理的使用多线程,能提高CPU密集型程序的执行效率。
合理的使用多线程,能提高IO密集型程序的用户体验(如生活中我们一边写代码一边下载开发工具,就是多线程运行的一种表现)。

二、C++线程库

1.thread类的简单介绍

C++11 之前,涉及到多线程问题,都是和平台相关的,比如 windows linux 下各有自己的接
口,这使得代码的可移植性比较差 C++11 中最重要的特性就是对线程进行支持了,使得 C++
并行编程时不需要依赖第三方库 ,而且在原子操作中还引入了原子类的概念。要使用标准库中的
线程,必须包含 < thread > 头文件。
以下是线程相关的函数:
函数名: thread()   功能:构造一个线程对象,没有关联任何线程函数,即没有启动任何线程
函数名:
thread(fn,
args1, args2,
...)     这里的...是可变参数列表,我会在后面深入学习线程的文章中详细介绍。   功能: 构造一个线程对象,并关联线程函数fnargs1args2...为线程函数的参数
函数名:get_id()     功能:获取线程id
函数名: jionable()   功能:线程是否还在执行,joinable代表的是一个正在执行中的线程。
函数名: jion()     功能:该函数调用后会阻塞住线程,当该线程结束后,主线程继续执行
函数名: detach()    功能:在创建线程对象后马上调用,用于把被创建线程与线程对象分离开,分离的线程变为后台线程,创建的线程的"死活"就与主线程无关
注意:
1. 线程是操作系统中的一个概念, 线程对象可以关联一个线程,用来控制线程以及获取线程的
状态
2. 当创建一个线程对象后,没有提供线程函数,该对象实际没有对应任何线程。如下图:
#include <thread>
#include <iostream>
using namespace std;
int main()
{
 std::thread t1;
 cout << t1.get_id() << endl;
 return 0;
}

 上图中get_id的返回值类型为id类型,id类型实际为std::thread命名空间下封装的一个类,该类中包含一个结构体,如下:

// vs下查看
typedef struct
{ /* thread identifier for Win32 */
 void *_Hnd; /* Win32 HANDLE */
 unsigned int _Id;
} _Thrd_imp_t;

3.当创建一个线程对象后,并且给线程关联线程函数,该线程就被启动,与主线程一起运行。 线程函数一般情况下可按照以下三种方式提供:  1.函数指针   2.lambda表达式   3.函数对象

以下为三种方式的代码:

#include <iostream>
using namespace std;
#include <thread>
void ThreadFunc(int a)
{
 cout << "Thread1" << a << endl;
}
class TF
{
public:
 void operator()()
 {
 cout << "Thread3" << endl;
 }
};
int main()
{
 // 线程函数为函数指针
 thread t1(ThreadFunc, 10); 
 // 线程函数为lambda表达式
 thread t2([]{cout << "Thread2" << endl; });
 // 线程函数为函数对象
 TF tf;
 thread t3(tf);
 t1.join();
 t2.join();
 t3.join();
 cout << "Main thread!" << endl;
 return 0;
}

4.thread类是防拷贝的,不允许拷贝构造以及赋值,但是可以移动构造和移动赋值,即将一个

线程对象关联线程的状态转移给其他线程对象,转移期间不意向线程的执行。
5.可以通过jionable()函数判断线程是否是有效的,如果是以下任意情况,则线程无效:
1.采用无参构造函数构造的线程对象。
2.线程对象的状态已经转移给其他线程对象
3.线程已经调用jion或者detach结束

2.线程函数参数

线程函数的参数是以值拷贝的方式拷贝到线程栈空间中的 ,因此:即使线程参数为引用类型,在
线程中修改后也不能修改外部实参,因为 其实际引用的是线程栈中的拷贝,而不是外部实参
演示代码如下:
#include <thread>
void ThreadFunc1(int& x)
{
 x += 10;
}
void ThreadFunc2(int* x)
{
 *x += 10;
}
int main()
{
 int a = 10;
 // 在线程函数中对a修改,不会影响外部实参,因为:线程函数参数虽然是引用方式,但其实际
引用的是线程栈中的拷贝
 thread t1(ThreadFunc1, a);
 t1.join();
 cout << a << endl;
 // 如果想要通过形参改变外部实参时,必须借助std::ref()函数
 thread t2(ThreadFunc1, std::ref(a);
 t2.join();
 cout << a << endl;
 // 地址的拷贝
 thread t3(ThreadFunc2, &a);
 t3.join();
 cout << a << endl;
 return 0;
}
注意:如果是类成员函数作为线程参数时,必须将this作为线程函数参数。
以上就是线程的一小部分的简单学习,我们这篇文章的深度很浅很浅,就是给初学者看一看,对于更深入的c++11的所有新特性我会在后面的文章中详细并且深入的讲解。

总结

c++11新特性中的lambda和线程都是值得学习的,由于我现在对lambda和线程学习的很浅所以本篇文章只是讲了我目前所简单学到的一些知识,在后面的文章中我会详细的重新介绍lambda函数以及线程等c++11新特性的学习。

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

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

相关文章

day3 TCP/IP协议与五层体系结构

TCP / IP 四层体系结构 TCP / IP工作流程&#xff1a; 现在互联网使用的 TCP/IP 体系结构已经发生了演变&#xff0c;即某些应用程序可以直接使用 IP 层&#xff0c;或甚至直接使用最下面的网络接口层。 沙漏型展示&#xff1a; 五层体系结构 各层的主要功能 应用层&#xff1…

搭建外网minecraft服务器方案

很多minecraft服务器主都想自己搭建一个外网可以访问的minecraft服务器&#xff0c;在没有外网IP的情况下&#xff0c;一般都是使用Logmein Hamachi方案。这种方案有它的弊端&#xff0c;需要客户机安装Hamachi&#xff0c;十分不方便。另外&#xff0c;免费版只支持5人&#x…

mysql如何加行锁

一、概述 InnoDB 引擎是支持行级锁的&#xff0c;而 MyISAM 引擎并不支持行级锁&#xff0c;所以后面的内容都是基于 InnoDB 引擎的。当我们使用delete、update进行数据库删除、更新的时候&#xff0c;数据库会自动加上行锁。但是&#xff0c;行锁有时也会失效。 数据库版本&a…

笔记:计算机网络体系结构(OSI七层模型、TCP/IP五层协议)

计算机网络体系结构 计算机网络是一个复杂的、具有综合性技术的系统&#xff0c;它由计算机系统、通信处理机、通信线路和通信设备、操作系统以及网络协议等组成。为了更好地描述计算机网络结构&#xff0c;使计算机网络系统有条不紊地处理工作&#xff0c;需要定义一种较好的…

CH9121网络串口透传应用

概述 随着物联网技术的普及&#xff0c;越来越多的传统设备出现联网功能需求。串口作为使用较为广泛的一种通信接口&#xff0c;串口转以太网&#xff0c;进行远程数据传输需求逐渐显现出来。CH9121内部集成TCP/IP协议栈&#xff0c;无需编程&#xff0c;即可轻松实现网络数据…

【SWAT水文模型】SWAT水文模型建立及应用第二期:土地利用数据的准备

SWAT水文模型建立及应用&#xff1a;土地利用数据的准备 1 简介2 土地利用数据的下载2.1 数据下载方式2.1.1 中科院1km土地利用数据2.1.2 清华大学高精度土地利用数据 2.2 数据下载 3 土地利用数据的准备3.1 矢量转栅格3.2 土地利用类型的重分类3.3 土地利用分布图投影调整3.4 …

【LeetCode】213. 打家劫舍 II

213. 打家劫舍 II&#xff08;中等&#xff09; 思路 这道题是 198.打家劫舍 的拓展版&#xff0c;区别在于&#xff1a;本题的房间是环形排列&#xff0c;而198.题中的房间是单排排列。 将房间环形排列&#xff0c;意味着第一间房间和最后一间房间不能同时盗窃&#xff0c;因…

EPIT定时器实验(一)

EPIT定时器简介 EPIT&#xff1a;Enhanced Periodic Interrupt Timer&#xff0c;直译就是增强的周期中断定时器&#xff0c;它主要完成周期性中断定时的。 STM32里面的定时器有很多其它功能&#xff0c;比如输入捕获、PWM输出等&#xff0c;但是I.MX6U的的EPIT定时器只是完成…

【五一创作】数据可视化之美 ( 三 ) - 动图展示 ( Python Matlab )

1 Introduction 在我们科研学习、工作生产中&#xff0c;将数据完美展现出来尤为重要。 数据可视化是以数据为视角&#xff0c;探索世界。我们真正想要的是 — 数据视觉&#xff0c;以数据为工具&#xff0c;以可视化为手段&#xff0c;目的是描述真实&#xff0c;探索世界。 …

CSS布局之圣杯布局/双飞翼布局

&#x1f4dd;个人主页&#xff1a;爱吃炫迈 &#x1f48c;系列专栏&#xff1a;HTMLCSS &#x1f9d1;‍&#x1f4bb;座右铭&#xff1a;道阻且长&#xff0c;行则将至&#x1f497; 文章目录 圣杯布局HTML代码步骤CSS代码 双飞翼布局HTML代码步骤CSS代码 小结 圣杯布局 HTM…

Java --- springboot2的静态资源配置原理

目录 一、静态资源配置原理 1.1、配置类只有一个有参构造器 1.2、资源处理的默认规则 1.3、欢迎页的处理规则 一、静态资源配置原理 springboot启动默认加载xxxAutoConfiguration(自动配置) springmvc功能的自动配置类&#xff0c;生效 Configuration(proxyBeanMethods …

《编码——隐匿在计算机软硬件背后的语言》精炼——第13-14章(二进制减法器——1位存储器)

“成功不是最终的&#xff0c;失败不是致命的&#xff0c;勇气才是最关键的。” - 温斯顿丘吉尔 文章目录 如何实现减法计算机进行减法运算的逻辑借位的代替机制二进制下的替代机制 减法的电路实现 反馈与触发器电铃触发器R-S触发器 电平触发的D型触发器 如何实现减法 计算机进…

霍兰德人格分析雷达图

雷达图 Radar Chart 雷达图是多特性直观展示的重要方式 问题分析 霍兰德认为&#xff1a;人格兴趣与职业之间应有一种内在的对应关系 人格分类&#xff1a;研究型、艺术型、社会型、企业型、传统型、现实性 职业&#xff1a;工程师、实验员、艺术家、推销员、记事员、社会工…

1992-2022年31省人均gdp/各省人均地区生产总值

1992-2022年31省人均gdp/各省人均地区生产总值 1、时间&#xff1a;1992-2022年 2、来源&#xff1a;国家统计J、各省NJ 3、范围&#xff1a;包括31省 4、缺失情况说明&#xff1a;无缺失 5、指标包括&#xff1a;各省人均GDP/省人均地区生产总值 6、指标解释&#xff1a…

五一劳动节前 特辑 ,路上那些车不能碰 你赔不起系列

相信明天大家4月29日都上了高速&#xff0c;都奔赴自己今年第一个想去的地方&#xff0c;那么上了高速&#xff0c;见的车辆就多了&#xff0c;哪些车辆我们要明白&#xff0c;尽量不要去碰&#xff0c;或者看见进行 技术性躲避&#xff0c;因为碰一下&#xff0c;半套房没了&a…

Vue3超详细的ref()用法,看这一篇就够了

ref()接受一个内部值&#xff0c;返回一个响应式的、可更改的 ref 对象&#xff0c;此对象只有一个指向其内部值的属性 .value。 ref() 将传入参数的值包装为一个带 .value 属性的 ref 对象。 1、ref 对象是可更改的&#xff0c;即可以为 .value 赋予新的值 举例&#xff1a; c…

【chatgpt】学习开源项目chatgpt-web,搭建自己的chatgpt服务,功能非常丰富有打字效果

目录 前言1&#xff0c;开源的chatgpt项目2&#xff0c;项目可以直接使用docker-compose跑起来3&#xff0c;关于打字模式SSE&#xff0c; octet-stream &#xff08;打字特效&#xff09;4&#xff0c;关于内容存储5&#xff0c;总结 前言 本文的原文连接是: https://blog.csd…

线性结构的存储类型

线性结构的存储类型 顺序标&#xff1a;顺序标就是数组&#xff0c;也成为向量vector、高维向量及称为张量即tensor 链表&#xff1a;单链表、双链表、循环链表 线性表概念 表目、文件、索引、表的长度、空表 线性表由节点表和关系表组成二元组&#xff1b; 节点集由有限的…

Hadoop 1:Apache Hadoop、HDFS

Hadoop核心组件 Hadoop HDFS&#xff08;分布式文件存储系统&#xff09;&#xff1a;解决海量数据存储 Hadoop YARN&#xff08;集群资源管理和任务调度框架&#xff09;&#xff1a;解决资源任务调度 Hadoop MapReduce&#xff08;分布式计算框架&#xff09;&#xff1a;解决…

全景丨0基础学习VR全景制作,平台篇第13章:热点功能-总览介绍

全景丨0基础学习VR全景制作&#xff0c;平台篇第13章&#xff1a;热点功能-总览介绍 大家好&#xff0c;欢迎观看蛙色VR官方——后台使用系列课程&#xff01; 一、热点功能概览 热点&#xff0c;指在全景作品中添加各种类型图标的按钮&#xff0c;引导用户通过按钮产生更多的…