多线程编程
什么是多线程,线程是操作系统能够进行运算调度的最小单位。他包含在进程之中,是进程中的实际运作单位。线程是进程中一个单顺序的空值六,一个进程可以并发多个线程,每个线程可以并行处理不同的任务。
threading模块
python的标准库提供了两个模块用于多线程处理,_thread和threading,_thread是低级模块,threading是高级模块,是对_thread进行了封装。
启动一个线程就是把一个函数传入并创建Thread实例,然后调用start()开始执行:
线程有两种调用方式:直接调用和继承式调用
直接调用
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 |
|
继承式调用
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 |
|
守护线程
默认情况下,线程执行完毕如果该线程下还有子线程没有执行完毕才会结束,我们可以通过守护线程的方式,是的主线程执行完毕强制结束下面的子线程的运行
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 |
|
输出结果
1 2 3 4 5 6 7 |
|
可以看出,main线程下的子线程执行的时间要比main线程时间长,当main线程执行完的时候,子线程的print
(
‘--done--‘
)还没有执行就被强制结束了
锁
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 |
|
正常情况,启动10000个线程,每个线程对num做加1操作,最终的结果将是10000,但是如果你用python2.X版本的解释器执行上面的代码会发现,最结果不总是10000,而且随着线程越多,这个最终结果的值稳定性越差,这就需要在对需要修改线程间共享的变量的时候加一把锁,当一个线程获得锁并操作一个共享变量的时候,其他线程只能等待锁释掉才可以,等待的过程是阻塞的,只有锁被释放掉,其他线程中“抢”到锁的进程才可以继续进行
申请锁
1 |
|
释放锁
1 |
|
注意,Python3.X已经修复了这个问题,不用加锁结果也是正确的
递归锁
递归锁说白了就是一个大锁里面套着小锁,也就是子锁,用到的地方不多,就不说了
信号量(Semaphore)
刚才说的锁也是互斥锁,同事只能有一个线程操作,而Semaphore可以同事允许一定数量的线程更改数据。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 |
|
事件Event
事件可以裂解为就是一个信号,他只有两个状态可以理解为真和假,常用方法如下
- set():相当于设置为真
- clear():相当于设置为假
- isSet():判断是否为真
- wait():等待事件置为真(阻塞)
?事件做常用的一个地方就是红绿灯模型,下面代码这就是演示红绿灯模型
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 |
|