1. 多线程编程

在进行桌面应用程序开发的时候, 假设应用程序在某些情况下需要处理比较复杂的逻辑, 如果只有一个线程去处理,就会导致窗口卡顿,无法处理用户的相关操作。这种情况下就需要使用多线程,其中一个线程处理窗口事件,其他线程进行逻辑运算,多个线程各司其职,不仅可以提高用户体验还可以提升程序的执行效率。

如果要使用Qt的多线程编程的话,可以看这篇

Qt多线程编程

这篇我重点记录一下C++11中的多线程编程方法

2. std::thread

C++11中加入了头文件,此头文件主要声明了std::thread线程类。C++11的标准类std::thread对线程进行了封装,定义了C++11标准中的一些表示线程的类、用于互斥访问的类与方法等。应用C++11中的std::thread便于多线程程序的移值。

std::thread类成员函数:

(1)、get_id:获取线程ID,返回一个类型为std::id的对象。

(2)、joinable:检查线程是否可被join。检查thread对象是否标识一个活动(active)的可行性线程。缺省构造的thread对象、已经完成join的thread对象、已经detach的thread对象都不是joinable。

(3)、join:调用该函数会阻塞当前线程。阻塞调用者(caller)所在的线程直至被join的std::thread对象标识的线程执行结束。

(4)、detach:将当前线程对象所代表的执行实例与该线程对象分离,使得线程的执行可以单独进行。一旦线程执行完毕,它所分配的资源将会被释放。

(5)、native_handle:该函数返回与std::thread具体实现相关的线程句柄。native_handle_type是连接thread类和操作系统SDK API之间的桥梁,如在Linux g++(libstdc++)里,native_handle_type其实就是pthread里面的pthread_t类型,当thread类的功能不能满足我们的要求的时候(比如改变某个线程的优先级),可以通过thread类实例的native_handle()返回值作为参数来调用相关的pthread函数达到目录。This member function is only present in class thread if the library implementation supports it. If present, it returns a value used to access implementation-specific information associated to the thread.

(6)、swap:交换两个线程对象所代表的底层句柄。

(7)、operator=:moves the thread object

(8)、hardware_concurrency:静态成员函数,返回当前计算机最大的硬件并发线程数目。基本上可以视为处理器的核心数目。

另外,std::id表示线程ID,定义了在运行时操作系统内唯一能够标识该线程的标识符,同时其值还能指示所标识的线程的状态。Values of this type are returned by thread::get_id and this_thread::get_id to identify threads.

有时候我们需要在线程执行代码里面对当前调用者线程进行操作,针对这种情况,C++11里面专门定义了一个命名空间this_thread,此命名空间也声明在头文件中,其中包括get_id()函数用来获取当前调用者线程的ID;yield()函数可以用来将调用者线程跳出运行状态,重新交给操作系统进行调度,即当前线程放弃执行,操作系统调度另一线程继续执行;sleep_until()函数是将线程休眠至某个指定的时刻(time point),该线程才被重新唤醒;sleep_for()函数是将线程休眠某个指定的时间片(time span),该线程才被重新唤醒,不过由于线程调度等原因,实际休眠实际可能比sleep_duration所表示的时间片更长。

2.1 创建一个线程

直接使用std::thread 来实例化

#include <iostream>
#include <thread>
#include <stdlib.h> //sleep using namespace std; void t1()
{
for (int i = 0; i < 10; ++i)
{
cout << "博客园-进击的汪sir\n";
sleep(1);
}
}
void t2()
{
for (int i = 0; i < 20; ++i)
{
cout << "1111111111111\n";
sleep(1);
}
}
int main()
{
thread th1(t1); //实例化一个线程对象th1,使用函数t1构造,然后该线程就开始执行了(t1())
thread th2(t2); th1.join(); // 必须将线程join或者detach 等待子线程结束主进程才可以退出
th2.join(); //or use detach
//th1.detach();
//th2.detach(); cout << "here is main\n\n"; return 0;
}

2.2 lambda表达式

用lambda表达式来执行多线程非常的方便,适合处理一些比较小的任务

std::thread t3([](int a, double b){cout << a << ' ' << b << endl;}, 3, 4);

3. join与detach的区别

每一个程序至少拥有一个线程,那就是执行main()函数的主线程,而多线程则是出现两个或两个以上的线程并行运行,即主线程和子线程在同一时间段同时运行。而在这个过程中会出现几种情况:

主线程先运行结束

子线程先运行结束

主子线程同时结束

在一些情况下需要在子线程结束后主线程才能结束,而一些情况则不需要等待,但需注意一点,并不是主线程结束了其他子线程就立即停止,其他子线程会进入后台运行

3.1 join()

join()函数是一个等待线程完成函数,主线程需要等待子线程运行结束了才可以结束

#include <iostream>
#include "thread"
using namespace std;
void func()
{
for(int i = 0; i <3; i++)
{
cout << "from func():" << i << endl;
}
} int main() {
std::cout << "Hello, World!" << std::endl;
std::cout << "Hello, World!" << std::endl;
thread t1(func);
thread::id t1_id = t1.get_id();
thread::id this_id = this_thread::get_id();
t1.join(); std::cout << "t1_id:" << t1_id << endl;
std::cout << "this_id: " << this_id <<endl;
return 0;
}

运行结果

3.2 detach()

称为分离线程函数,使用detach()函数会让线程在后台运行,即说明主线程不会等待子线程运行结束才结束

通常称分离线程为守护线程(daemon threads),UNIX中守护线程是指,没有任何显式的用户接口,并在后台运行的线程。这种线程的特点就是长时间运行;线程的生命周期可能会从某一个应用起始到结束,可能会在后台监视文件系统,还有可能对缓存进行清理,亦或对数据结构进行优化。另一方面,分离线程的另一方面只能确定线程什么时候结束,发后即忘(fire andforget)的任务就使用到线程的这种方式

#include <iostream>
#include "thread"
using namespace std;
void func()
{
for(int i = 0; i <3; i++)
{
cout << "from func():" << i << endl;
}
} int main() {
thread t1(func);
thread::id t1_id = t1.get_id();
std::cout << "Hello, World!" << std::endl;
thread::id this_id = this_thread::get_id();
t1.detach();
std::cout << "Hello, World!" << std::endl;
std::cout << "t1_id:" << t1_id << endl;
std::cout << "this_id: " << this_id <<endl;
return 0;
}

运行结果

4. 参考

https://blog.csdn.net/sevenjoin/article/details/82187127

C++11多线程编程的更多相关文章

  1. C++11 多线程编程 使用lambda创建std::thread (生产/消费者模式)

    要写个tcp server / client的博客,想着先写个c++11多线程程序.方便后面写博客使用. 目前c++11中写多线程已经很方便了,不用再像之前的pthread_create,c++11中 ...

  2. C++11多线程编程--线程创建

    参考资料 adam1q84 我是一只C++小小鸟 Thread support library Book:<C++ Concurrency in Action> 线程的创建 线程的创建有多 ...

  3. C++11 多线程编程

    http://blog.csdn.net/column/details/ccia.html?&page=1

  4. C++11多线程编程(常见面试题)

    [题目1] 子线程循环 10 次,接着主线程循环 100 次,接着又回到子线程循环 10 次,接着再回到主线程又循环 100 次,如此循环50次,试写出代码 [题解] 首先我们来分析一下这道题...( ...

  5. C++11多线程教学(二)

    C++11多线程教学II 从我最近发布的C++11线程教学文章里,我们已经知道C++11线程写法与POSIX的pthreads写法相比,更为简洁.只需很少几个简单概念,我们就能搭建相当复杂的处理图片程 ...

  6. C++11多线程教学II

    从我最近发布的C++11线程教学文章里,我们已经知道C++11线程写法与POSIX的pthreads写法相比,更为简洁.只需很少几个简单概念,我们就能搭建相当复杂的处理图片程序,但是我们回避了线程同步 ...

  7. c++11并行、并发与多线程编程

    首先,我们先理解并发和并行的区别. 你吃饭吃到一半,电话来了,你一直到吃完了以后才去接,这就说明你不支持并发也不支持并行. 你吃饭吃到一半,电话来了,你停了下来接了电话,接完后继续吃饭,这说明你支持并 ...

  8. C++11 并发编程基础(一):并发、并行与C++多线程

    正文 C++11标准在标准库中为多线程提供了组件,这意味着使用C++编写与平台无关的多线程程序成为可能,而C++程序的可移植性也得到了有力的保证.另外,并发编程可提高应用的性能,这对对性能锱铢必较的C ...

  9. C++ 11 多线程--线程管理

    说到多线程编程,那么就不得不提并行和并发,多线程是实现并发(并行)的一种手段.并行是指两个或多个独立的操作同时进行.注意这里是同时进行,区别于并发,在一个时间段内执行多个操作.在单核时代,多个线程是并 ...

随机推荐

  1. Mybatis学习笔记-复杂查询

    多个学生,对应一个老师 对于学生而言,关联:多个学生关联一个老师[多对一] 对于老师而言,集合:一个老师,有多个学生[一对多] 复杂查询环境搭建 数据库搭建 CREATE TABLE `teacher ...

  2. iptables中实现内外网互访,SNAT和DNAT

    目录 一.SNAT原理与应用 二.DNAT原理与应用 DNAT转换:发布内网web服务 DNAT转换:发布时修改目标端口 三.防火墙规则的备份和还原 四.linux抓包 一.SNAT原理与应用 ① S ...

  3. 2010 NOIP提高组题解

    机器翻译 用队列模拟题意即可 #include<cstdio> #include<iostream> #include<cstring> using namespa ...

  4. JVM 内存分配、调优案例

    内存分配 对象优先在Eden区分配 大多数情况下,对象在新生代Eden区中分配.当Eden区没有足够空间进行分配时,虚拟机将发起一次Minor GC. HotSpot虚拟机提供了-XX:+PrintG ...

  5. Spring Cloud Alibaba - RestTemplate

    Spring Cloud Alibaba - RestTemplate Controller导入依赖和相关属性 @SuppressWarnings("all") @RestCont ...

  6. 常见的Web攻击手段,拿捏了!

    大家好,我是小菜. 一个希望能够成为 吹着牛X谈架构 的男人!如果你也想成为我想成为的人,不然点个关注做个伴,让小菜不再孤单! 本文主要介绍 互联网中常见的 Web 攻击手段 如有需要,可以参考 如有 ...

  7. 跟我一起写 Makefile(十二)

    隐含规则 ---- 在我们使用Makefile时,有一些我们会经常使用,而且使用频率非常高的东西,比如,我们编译C/C++的源程序为中间目标文件(Unix下是[.o]文件,Windows下是[.obj ...

  8. MyBatis学习01(初识MyBatis和CRUD操作实现)

    1.初识MyBatis 环境说明: jdk 8 + MySQL 5.7.19 maven-3.6.1 IDEA 学习前需要掌握: JDBC MySQL Java 基础 Maven Junit 什么是M ...

  9. python3+telnetlib实现简单自动测试

    1 telnetlib介绍 1.1 简介 官方介绍文档:telnetlib -- Telnet 客户端 - Python 3.9.6 文档 telnetlib 模块提供一个实现Telnet协议的类 T ...

  10. 【笔记】衡量线性回归法的指标 MSE,RMS,MAE以及评价回归算法 R Square

    衡量线性回归法的指标 MSE,RMS,MAE以及评价回归算法 R Square 衡量线性回归法的指标 对于分类问题来说,我们将原始数据分成了训练数据集和测试数据集两部分,我们使用训练数据集得到模型以后 ...