在《python多线程技术(一)》篇当中,曾粗略介绍了多线程技术及运行状态,及python对于多线程的支持和简单实用,还有印象的朋友一定还记得python中实现多线程的两种方式吧,如果不熟悉的话,建议你先去读一读我上一篇的博文哦🤓

本篇是python多线程技术的精华所在,在真实项目开发中所使用到的多线程编程模型大部分都可以在我将要给出的代码示例中找到,如果本篇的内容过于繁多的话,按照我一如既往,短小精悍的写作特点来看的话~我也许还会写上第三篇哦😛

常见线程运行模型

在开始撸码之前,我们还是看看的常见的线程模型有哪些~一起看看这些言简意赅,图文并茂的示意图(感谢麦子学院丁敬香老师提供的教学资料)

1.井水不犯河水井水不犯河水
2.独木桥上相遇-线程等待独木桥上相遇-线程等待
3.甘当幕后英雄-后台线程甘当幕后英雄-后台线程
4. 我先用你后用-线程同步我先用你后用-线程同步
5.操作也有先后-线程同步操作也有先后-线程同步
6共享要悠着用-线程同步共享要悠着用-线程同步
7.我用完后叫你-线程通信我用完后叫你-线程通信

具体代码实例

#####1. 线程等待实例

在python的多线程编程中实现线程的等待非常容易,只需要调用线程对象的join(self, timeout=None)方法即可

被调用join()方法的线程会一直阻塞调用者的线程,直到自己结束(正常结束,或引发未处理异常),或超出timeout的时间。

1.1.1 一般情形

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
import threading
import time

class MyThread(threading.Thread):
def run(self):
for i in range(20):
print('threading: ', i)
time.sleep(0.1)

if __name__ == '__main__':
t = MyThread()
t.start()
#t.join() # 取消注释即转变为线程等待情形
for i in range(10):
print('Main:', i)
time.sleep(0.1)

运行结果如下
非等待

可以看到是两个线程交叉运行,如果我们需要在子线程运行完成后再运行主进程,调用join方法即可

1.1.2 等待情形

代码如上,取消join方法所在行的注释即可

运行结果如下
等待

2. 守护线程(后台线程)

在python中实现后台线程的情景相当容易,其步骤如下:

1.建立线程

2.设置线程的daemon属性为True

3.启动线程

需要注意的是被设定为后台运行的线程,会在主程序退出时主动自杀。

2.1.1 一般情形

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
import threading
import time

def dmn():
"""模拟后台线程的运行"""
print('dmn start ...')
time.sleep(2) # 后台线程来不及结束,将会随着主线程的结束而退出
print('dmn end.')


def ndmn():
"""非后台线程运行"""
print('ndmn start ...')
time.sleep(1)
print('ndmn end.')

if __name__ == '__main__':
d = threading.Thread(target=dmn)
#d.daemon= True # 模拟后台线程时,请取消次注释
n = threading.Thread(target=ndmn)
print('Main statr')
d.start()
n.start()
print('Main end.'

运行结果如下
非等待线程

可以看到主线程结束后,两个线程也相继结束

2.2.2 守护线程情形

代码如上,取消注释后,运行结果如下
守护线程

可以看到主线程结束后,守护线程就自动退出,还来不及执行print(‘dmn end.’)

3. 线程同步(重点,难点)

python中线程同步的方式纷繁复杂,多种多样,为处理不同业务情形提供相应的工具和概念。python的theading模块主要提供了以下3种线程同步的方式:

1.指令锁(Lock)

2.条件变量(Condition)

3.信号量(Semaphore)

3.1 指令锁
3.2 条件变量
3.3 信号量

留言

⬆︎TOP