线程
- 线程也可以使用计算机的多核资源,也是多任务编程方式之一。
- 线程又称为轻量级的进程,在并发上和进程相同但是在创建时消耗资源少。
- 一个进程中可以包含多个线程,这些线程共享进程的资源。
- 多个线程因为共享进程的资源,所在通信上往往采用全局变量的方法
- 线程也拥有自己特有的资源,比如TID,指令集等
多进程与多线的区别和联系
- 多进程和多线程都是多任务编程方法,都可以使用计算机多核
- 进程的创建要比线程消耗更多的资源
- 进程空间独立数据更安全,有专门的的进程间通信方式进行交互
- 一个进程包含多个线程,所以线程共享进程资源,没有专门的通信方法,依赖全局变量进行通信。往往需要使用同步互斥机制,逻辑需要思考更多。
- 进程线程都有自己特定的资源。多个关联任务的时候使用多线程资源消耗更少,如果是多个无关任务也不适于全使用线程。
创建线程
import threading
- 创建线程函数
threading.Tread()
- 功能:创建线程
- 参数:
target
线程函数
args
以元组的方式给线程函数传参
kwargs
以字典方式给线程函数传参
name
线程名称 - 返回值:返回线程对线
-
t.start()
启动一个线程 -
t.is_alive()
查看一个线程的状态 -
t.name
查看线程的名称 -
t.join(sec)
阻塞等待回收线程 -
daemon
属性
该属性默认为False
,主线程执行完毕不会影响到其他线程的执行;如果设置为True
,则主线程执行完毕其他线程也会终止执行。
t.setDaemon(True)
或t.daemon = True
设置daemon
属性
t.isDaemon()
获取daemon
属性值
线程间的通信
全局变量
线程的同步与互斥
线程event
-
e.wait(timeout)
如果e
被设置则不会阻塞,未被设置则阻塞,timeout
为超时阻塞时间 -
e.set()
将e
变为设置的状态 -
e.clear()
将e
变为未设置的状态
线程锁
threading.Lock()
-
lock.acquire()
上锁 -
lock.release()
解锁
创建自己的线程类
- 自定义类继承于原有线程类
- 复写原有的
run
方法 - 创建线程对线调用
start
的时候会自动执行run
线程池模块
第三方模块:threadpool
安装线程池模块:sudo pip3 install threadpool
全局解释器锁(GIL)
python -> 支持多线程 -> 同步和互斥 -> 加锁 -> 超级锁 -> 解释器在同一时刻只能解释一个线程
大量python库为了省事依赖于这种机制 -> python多线程效率低
-
GIL
即为从python
解释器由于上锁带来的同一个时刻只能解释一个线程的问题 - 解决方案:
- 不使用线程,转而使用进程
- 不使用
C
作为解释器,Java
,C#
都可以做python
解释器
- 两种程序
-
IO
密集型- 程序中进行了大量
IO
操作,只有少量的CPU
操作 - 在内存中进行了数据的交换的操作都可以认为是
IO
操作 - 特点
速度较慢,使用CPU
不高
- 程序中进行了大量
-
CPU
密集型(计算密集型)- 大量的程序都在进行运算操作
- 特点
CPU
占有率高
-
效率测试
- 多线程的工作效率和单线程几乎相近
- 多进程要比单线程和多进程有明显的效率提升
设计模式
设计模式代表了一种最佳实践,是被开发人员长期开发总结,用来解决某一类问题的思路方法。这些方法保证了代码的效率也易于理解。
生产者消费者模式
- 高内聚:在同一模块内,实现单一功能,尽量不使功能混杂。
- 低耦合:不同的模块之间尽量互相独立,减少模块间的影响。
问题
- 进程和线程的区别
- 什么是同步和互斥?
- 给一个具体的情况,问采用进程还是线程?为什么?
- 如何处理僵尸进程?
- 如何测试一个硬盘的读写速度?
- xxx框架用的多进程还是多线程并发?
- 进程间通信方式有哪些?各自有什么特点?
网友评论