线程定时器
import time
from threading import Timer
def task():
print('线程 start')
time.sleep(2)
print('线程 end')
t = Timer(4, task) # 4s以后开启一个线程
t.start()
进程池、线程池
进程池、线程池的功能:限制进程数或线程数
什么时候限制
当并发的任务数量远远大于计算机所能承受的范围,即无法一次性开启过多的任务数量,这时候应该考虑去限制我进程数或线程数,从而保证服务器不崩溃。
进程池、线程池和信号量的区别
进程池始终不会产生新的进程,如ProcessPoolExecutor(3),所有的任务都是由这3个进程执行的。
from concurrent.futures import ProcessPoolExecutor,ThreadPoolExecutor
from multiprocessing import current_process
from threading import currentThread
import time
def task(i):
print(f'线程{currentThread().name} 在执行任务{i}')
time.sleep(2)
return i ** 2
if __name__ == '__main__':
pool = ThreadPoolExecutor(3)
fu_list = []
for i in range(15):
future = pool.submit(task, i)
fu_list.append(future)
pool.shutdown()
for fu in fu_list:
print(fu.result())
提交任务的两种方式
同步:提交了一个任务,必须等任务执行完了,才能执行下一行代码。
异步:提交了一个任务,不用等任务执行完,可以直接执行下一行代码。
回调函数
为当前任务绑定一个函数,在当前任务执行结束的时候会触发这个函数,这个函数称之为回调函数。
协程
python的线程用的是操作系统原生的线程
协程:单线程下实现并发
什么样的协程是有意义的
遇到IO切换的时候才有意义
协程的具体概念
协程概念本质是程序员自己抽象出来的,操作系统根本不知道协程的存在,也就是说来一个线程遇到了IO,线程内部直接自己切换到别的任务上了,操作系统根本发现不了,也就实现了单线程下效率最高。
优点:自己控制切换要比操作系统控制切换快的多
缺点:对比多线程,自己要检测所有的IO,但凡有一个阻塞,整体都会跟着阻塞
对比多进程,无法利用多核优势