线程
1. 线程
1. 介绍
想要实现多任务,除了使用进程,还可以使用线程来完成,线程是实现多任务的另一种方式。
2. 概念
线程是进程中执行代码的一个分支,每个执行分支(线程)要想执行代码需要cpu进行调度,线程是cpu调度的基本单位,每个进程至少都有一个线程,而这个线程就是我们通常说的主线程。
3. 作用
多线程可以完成多任务
4. 运用
1. 导入线程模块
import threading
2. 语法
Thread([group [, target [, name [, args [, kwargs]]]]])
- group:线程组,目前只能使用None
- target:执行的目标任务名
- name:以元组的方式给执行任务传参
- args:以字典的方式给执行任务传参
- kwargs:
3. 示例
- 无参数
import threading import time def prt_cb1(): for i in range(3): print("cb1") time.sleep(0.3) def prt_cb2(): for i in range(3): print("cb2") time.sleep(0.3) if __name__ == '__main__': prt_cb1_thread = threading.Thread(target=prt_cb1) prt_cb2_thread = threading.Thread(target=prt_cb2) prt_cb1_thread.start() prt_cb2_thread.start() # 输出结果 cb1 cb2 cb2 cb1 cb1 cb2
- 有参数
import threading def prt_info(name): print(name) if __name__ == '__main__': prt_info_thread = threading.Thread(target=prt_info, kwargs={"name": "cb"}) prt_info_thread.start() # 输出结果 cb
4. 注意点
- 线程之间执行是无序的
- 主线程会等待所有的子线程执行结束再结束
- 线程之间共享全局变量
- 线程之间共享全局变量数据出现错误问题
- 解决方法:线程同步(保证同一时刻只能有一个线程去操作全局变量 同步:就是协同步调,按预定的先后次序进行运行。)
- 线程同步的方式:线程等待(join)、互斥锁
5. 互斥锁
1. 概念:对共享数据进行锁定,保证同一时刻只能有一个线程去操作。
2. 注意
* 互斥锁是多个线程一起去抢,抢到锁的线程先执行,没有抢到锁的线程需要等待,等互斥锁使用完释放后,其它等待的线程再去抢这个锁。
3. 作用
- 语法
# 创建锁 mutex = threading.Lock() # 上锁 mutex.acquire() …… # 释放锁 mutex.release() # 注意: # acquire和release方法之间的代码同一时刻只能有一个线程去操作 # 如果在调用acquire方法的时候,其他线程已经使用了这个互斥锁,那么此时acquire方法会堵塞,直到这个互斥锁释放后才能再次上锁。 # 线程等待和互斥锁都是把多任务改成单任务去执行,保证了数据的准确性,但是执行性能会下降
- 示例
import threading i_sum = 0 th_lock = threading.Lock() def th_sum1(): th_lock.acquire() for i in range(100000): global i_sum i_sum += 1 print("th_sum1:", i_sum) th_lock.release() def th_sum2(): th_lock.acquire() for i in range(100000): global i_sum i_sum += 1 print("th_sum2:", i_sum) th_lock.release() if __name__ == '__main__': th_sum1_thread = threading.Thread(target=th_sum1) th_sum2_thread = threading.Thread(target=th_sum2) th_sum1_thread.start() th_sum2_thread.start() # 输出结果 th_sum1: 100000 th_sum2: 200000
6. 死锁
1. 概念:一直等待对方释放锁的情景就是死锁
7. 进程和线程的对比
1. 关系对比
- 线程是依附在进程里面的,没有进程就没有线程。
- 一个进程默认提供一条线程,进程可以创建多个线程。
2. 区别对比
- 进程之间不共享全局变量
- 线程之间共享全局变量,但是要注意资源竞争的问题,解决方法:互斥锁或者线程同步
- 创建进程的资源开销要比创建线程的资源开销大
- 进程是操作系统资源分配的基本单位,线程是cpu调度的基本单位
- 线程不能独立执行,必须依存在进程中
- 多进程开发比单进程多线程开发稳定性要强
3. 优缺点
- 进程优缺点
- 优点:可以用多核
- 缺点:资源开销大
- 线程优缺点
- 优点:资源开销小
- 缺点:不能使用多核