并发编程之线程
2019-04-24 本文已影响0人
洛克黄瓜
启动与停止线程
- 库可以在单独的线程中执行任何的在Python中可以调用的对象
import time
from threading import Thread
def countdown(n):
while n > 0:
print('T-minus', n)
n -= 1
time.sleep(1)
t = Thread(target=countdown, args=(6,))
t.start()
t.join() # 调用线程t的join()函数,会把这个线程t加入到当前线程(这里就是主线程),当前线程就会等待线程t的终止,才执行后续内容
当你创建好一个线程对象后,该对象并不会立即执行,除非你调用它的start()方法(当你调用start()方法时,它会调用你传递进来的函数,并把你传递进来的参 数传递给该函数)。Python中的线程会在一个单独的系统级线程中执行(比如说一个POSIX线程或者一个Windows线程),这些线程将由操作系统来全权管理。线程一旦 启动,将独立执行直到目标函数返回。你可以查询一个线程对象的状态,看它是否还在 执行:
if t.is_alive():
print("Still running")
else:
print("Completed")
对于需要长时间运行的线程或者需要一直运行的后台任务,你应当考虑使用后台线程。这些线程会在主线程终止时自动销毁。例如:
t = Thread(target=countdown, args=(6,), daemon=True)
t.start()
- 由于全局解释锁(GIL)的原因,Python的线程被限制到同一时刻只允许一个线 程执行这样一个执行模型。所以, 的线程更适用于处理I/O和其他需要并发执 行的阻塞操作(比如等待I/O、等待从数据库获取数据等等),而不是需要多处理器并行的计算密集型任务。
线程间通信
- 线程间数据是共享的,没什么好说的
给关键部分加锁
image.png创建线程池
-
使用ThreadPoolExecutor相对于手动实现的好处是它使得任务提交者更方便的从被调用函数中获取返回值。
image.png
例子中返回的handle对象会帮你处理所有的阻塞与协作,然后从工作线程中返回数据给你。特别的, 操作会阻塞进程直到对应的函数执行完成并返回一个 结果。