深入理解线程、进程、多线程、线程池
QT多线程编程系列专栏文章共有12篇,全面的讲述、实现、运行了QT多线程的各种操作,包括运行原理、线程、进程、多线程、锁、QMutex、QSemaphore、 Emit、Sgnals、Slot、QWaitCondition、线程事件循环、QObjects、重入与线程安全、主线程子线程互相传值、线程同步与异步处理、线程的使用、浅拷贝、深拷贝、隐式共享、隐式共享机制对STL样式迭代器的影响等等文章。
本文以QT的方式来走进线程池的应用、线程、进程、线程池、线程锁、互斥量、信号量、线程同步等的详解,一文让你小白变大神 !
为什么要使用多线程、线程锁、互斥量、信号量? 为什么需要线程同步? 什么是线程池? 本文一文详解多线程。
本文作者原创首发于CSDN,本文原创请勿转载
版权声明:本文为CSDN博主「双子座断点」的原创文章,遵循CC 4.0 BY-SA版权协议。
原文链接:https://blog.csdn.net/qq_37529913/article/details/110127940
1. 线程进程的区别
线程,程序执行流的最小执行单位,是行程中的实际运作单位,经常容易和进程这个概念混淆。那么,线程和进程究竟有什么区别呢?首先,进程是一个动态的过程,是一个活动的实体。简单来说,一个应用程序的运行就可以被看做是一个进程,而线程,是运行中的实际的任务执行者。可以说,进程中包含了多个可以同时运行的线程。
上面话还是比较官方的,那么下来我给大家用大白话解释一下,方便大家面试的时候吊打面试官!
1.1 进程 :
- 进程就是一个应用,一个程序。
- 进程在计算机内存当中有单独的内存的应用。
- 进程里面可以有单个线程或者多个线程(单线程应用、多线程应用)。
1.2 线程:
- 进程中的最小执行单位就是线程,并且一个进程中至少有一个线程。
- 线程必须存在(依赖进程)应用里面,它无法单独存在。
- 线程在计算机当中没有单独的内存,它只能在进程的内存中存在。
- 线程一般是单线程,使用多线程必须得在进程里面设置(写多线程代码)。
1.3 线程的三种实现:
继承 QThread,重写 run() 接口;
使用 moveToThread() 方法将 QObject 子类移至线程中,内部的所有使用信号槽的槽函数均在线程中执行;
使用 QtConcurrent;
其实还有一种就是使用线程池QThreadPool也算一种方式
一般使用 QThread 重写run 来实现多线程 或者 使用信号和槽的方式来实现多线程就够用了
1.4 总结:
- 线程和进程是依赖关系
- 线程依赖于进程(应用)
- 进程就是应用
- 线程就是应用(进程)的实际执行者
PS:进程可以看成是脑子,线程可以看作是手脚嘴口鼻子耳朵,没有脑子就没有手脚口足,没有手脚口足只有脑子也没用。
看懂没?嗯哼?
2. 线程锁、互斥量、信号量、线程同步
2.1 线程锁
要保证某个资源在多线程的情况下的安全、可靠、顺序访问,可以使用线程锁,线程锁有两种一种是互斥量、一种是信号量。
接下来详解两种方法的优缺点和各自的特点。以QT程序为例(其它大同小异,原理相同)。
2.2 互斥量QMutex
QMutex类提供的是线程之间的访问顺序化。QMutex的目的是保护一个对象、数据结构或者代码段,所以同一时间只有一个线程可以访问它。
- 这句话话怎么理解呢?
- QMutex主要的作用是保护第一次访问到资源线程的安全
- 那么是什么情况下使用呢?
- 主要用来初始化、第一次读取资源、保证第一次初始化资源的安全、准确、不被其它线程干扰。
- 因为第一次初始化的资源变量参数已经被保存了,第二次和之后无论几次 就算改变这个变量参数,第一次保存的值是不受干扰的。
如果想进一步了解请参考博主的另一篇转载的线程锁文章: QT QMutex使用详解 QT QMutex使用详解_双子座断点的博客-CSDN博客_qt qmutex
先看完本篇文章在进一步了解不迟,那么使用QMutex锁会有什么问题呢
QMutex的作用只对 多线程中的第一次访问到资源的线程起作用 ! QMutex并不会对并发中的第二个线程第三个线程起作用,触发QMutex并不会阻塞后面的线程。
那么想要达到既要对线程起阻塞作用、又要保护资源在多线程中的顺序访问怎么办呢?那请看接下来的 信号量QSemaphore
2.3 信号量QSemaphore
QSemaphore也可以被用来使线程的执行顺序化,和QMutex的方法相似。信号量和互斥量的不同在于,信号量可以在同一时间被多于一个的线程访问。
- 这句话话怎么理解呢?
- 在多线程并发的情况下 (多个线程同时访问一块地方) 就会导致顺序错乱,与理想情况不一致。
- 创建三个线程打印A、B、C 打印五遍
- 情况 ABC ABC ABC ABC ABC
- 实际情况 ACB AAB CCA CCB ACB 、AAAAA BBBBB CCCCC 等等情况
- 怎么解决呢?当然是使用信号量QSemaphore !
- 使用信号量QSemaphore,这里最主要的就是"信号量"这三个字 !
如果想进一步了解请参考博主的另一篇原创文章:QT 线程之QSemaphore(深入理解) QT 线程之QSemaphore(深入理解)_双子座断点的博客-CSDN博客_qsemaphore用法
信号量最大的作用就是可以在多线程同时访问同一资源的时候使其顺序访问 !具体了解请点击连接文章有详尽的示例、实现、以及遇到的问题和作者总结的经验 !
看在我的这几个黑眼圈的份上希望大家点点关注、点点赞、点点收藏支持一下 \抱拳
3. 线程池和多线程的区别
- 线程池是在程序运行开始,创建好的n个线程,并且这n个线程挂起等待任务的到来。
- 而多线程是在任务到来得时候进行创建,然后执行任务。
- 线程池中的线程执行完之后不会回收线程,会继续将线程放在等待队列中;
- 多线程程序在每次任务完成之后会回收该线程。
- 由于线程池中线程是创建好的,所以在效率上相对于多线程会高很多。
- 线程池也在高并发的情况下有着较好的性能;不容易挂掉。
- 多线程在创建线程数较多的情况下,很容易挂掉。
3.1 多线程和线程池流程图
4. 线程池是什么?线程池的具体使用 !
- 线程池:
- 创建和销毁线程需要和OS交互,少量线程影响不大,但是线程数量太大,势必会影响性能,使用线程池可以这种开销:
- 线程池维护一定数量的线程,使用时,将指定函数传递给线程池,线程池会在线程中执行任务;
- 具体使用
- 作者个人观点:
- 一般中小型项目还是直接使用多线程好一点各个环节都自定义比较好点,多线程交互,统一创建销毁等。
- 大型项目使用线程池比多线程好点,线程池用起来比较方便有统一的管理、挂起唤醒都有封装用的时候只需要唤醒一个线程就好。
- 感觉这个还是看个人习惯和规定。
如果想进一步了解请参考博主的另一篇原创文章:QT 多线程之线程池QThreadPool(深入理解) CSDN
5. 多线程的各种操作
以下文章均为作者原创文章,看完记得收藏、关注加👍
线程、进程、多线程、线程池一文看懂从此秒变大佬!:深入理解线程、进程、多线程、线程池_双子座断点的博客-CSDN博客
QT 初识线程(简单实现):https://blog.csdn.net/qq_37529913/article/details/110127940
QT QMutex使用详解:https://blog.csdn.net/qq_37529913/article/details/110187452
QT 线程之QSemaphore(深入理解):https://blog.csdn.net/qq_37529913/article/details/110187121
QT线程 Emit、Sgnals、Slot详细解释:https://blog.csdn.net/qq_37529913/article/details/110211435
QT 线程之QWaitCondition(深入理解):https://blog.csdn.net/qq_37529913/article/details/110212704
Qt 多线程之线程事件循环(深入理解):https://blog.csdn.net/qq_37529913/article/details/110229382
QT线程之QObjects(深入理解):https://blog.csdn.net/qq_37529913/article/details/110228837
QT线程之可重入与线程安全(深入理解):https://blog.csdn.net/qq_37529913/article/details/110224166
QT 主线程子线程互相传值:QT 主线程子线程互相传值_双子座断点的博客-CSDN博客_qt主线程给子线程传数据
QT线程同步与异步处理:QT线程同步与异步处理_双子座断点的博客-CSDN博客_qt异步线程
QT 多线程之线程池QThreadPool(深入理解):QT 多线程之线程池QThreadPool(深入理解)_双子座断点的博客-CSDN博客_qthreadpool
QT之浅拷贝、深拷贝、隐式共享(深度理解必看文章):https://blog.csdn.net/qq_37529913/article/details/110235596
QT 隐式共享机制对STL样式迭代器的影响:https://blog.csdn.net/qq_37529913/article/details/110252454
- 点赞
- 收藏
- 关注作者
评论(0)