并发编程3
joinableQueue
在Queue的功能上多加了两个
1 task_done 告诉容器已经处理完了一个数据
2 join 也是哟个阻塞函数,一直到队列中的数据被处理完毕
(task_done的调用次数等于队列中的数据数量)
多线程理论
线程指的是一条流水线,是代码执行的总称,也是一个抽象概念
线程是CPU的最小执行单位,是具体负责执行代码的
进程是一个资源单位,其中包括了该程序运行所需的所有资源
线程的特点:
一个进程至少包含一个线程,是由操作系统自动创建的称之为主线程
一个进程中可以有任意数量的线程
创建线程的开销对比线程而言要小的多
同一个进程中的线程间数据共享(最主要的特点)
多线程两种创建方式
第一种直接实例化Thread
第二种继承Thread类,覆盖run方法
使用的方式与进程一致
不同的是:创建线程的代码可以写在任何位置
进程导入的模块 from multiprocessing import Process
线程导入的模块 from threading import Thread
主线程任务完毕后,进程不会立即结束,会等待所有子线程全部执行完毕
在同一给进程中,所有线程都是平等的没有父子这么一说
多线程
互斥锁
线程安全也是通过锁来保证,锁的用法与进程中一模一样
死锁
开发一些高并发程序很有可能出现线程/进程安全问题
解决方案只有加锁,但是在使用锁时,很有可能出现死锁问题
出现死锁问题的两种情况
1 对同一把锁调用了多次acquire导致死锁问题
2 有多把锁,一个线程抢一把锁,要完成任务必须同时抢到所有的锁,将导致死锁问题
如何避免:
1 能不加锁就不加 2 如果一定要加,保证锁只有一把
可重入锁
只能防止一个问题就是同一线程多次执行acquire
信息量
可以控制同一时间,有多少线程可以并发的访问
多线程的常用属性
Thread 对象常用属性
name 线程的名字
is_alive 返回线程是否活动
daemon 指定是否时守护线程
threading模块中常用数据
current_thread 获取当前线程
active_count 只在运行线程数量
enumerate 返回所有在运行的线程对象
守护线程
守护线程会在主线程结束后立即结束,即使任务没有完成
主线程会等待所有子进程全部完成后结束
守护线程会在所有非守护线程结束后结束