上文说到进程,已经分配好车间,口罩原料了,但是得有工人去操作机器才能生产出口罩,车间就相当于进程。车间里必须至少有一个工人才能完成制作口罩的工序,这就是单线程。但是工厂想提高效率,多安排几个工人去生产口罩,这就叫做多线程。
工人可以使用车间的所有资源,就是线程共享进程资源;
工人使用车间内的一个工作间(全局变量,共享内存)工作的时候,为了防止其他工人打扰,会上一把锁,工作完成才会取下,这是线程锁;
有的工作间可以同时容纳多个工人工作,于是就有多把钥匙,每个工人就拿上一把,所有钥匙被取完后,其他工人就只能等着,这是信号量(Semaphore);
有时候工人之间有合作,当一个工作间的工人工作到满足某个条件时,会发出通知并同时退出工作间,将钥匙交给另外符合条件正在等待的工人完成工作,这叫条件同步;例如员工人只负责把布料用叉车运输到指定的机床。原料抵达后就交给员工B操作,员工A则退出,因为已经不需要员工A了
还有一种工作模式,当一个工人完成到某个指标时,会将工作传递给其它等待这个指标触发的工人工作,这叫事件同步,例如员工A只负责做口罩绳,员工B负责做口罩上色,员工B上完色之后就递交给员工人挂好戴口罩的绳子
并发与并行
并发:当系统只有一个CPU时,想执行多个线程,CPU就会轮流切换多个线程执行,当有一个线程被执行时,其他线程就会等待,但由于CPU调度很快,所以看起来像多个线程同时执行
并行:当系统有多个CPU时,执行多个线程,就可以分配到多个CPU上同时执行
同步与异步
同步:调用者调用一个功能时,必须要等到这个功能执行完返回结果后,才能再调用其他功能
异步:调用者调用一个功能时,不会立即得到结果,而是在调用发出后,被调用功能通过状态、通知来通告调用者,或通过回调函数处理这个调用
先来一波单线程执行,同步堵塞
import threading
import time
def runOnce(sec,i):
print('循环到 %s',i)
time.sleep(sec)
if __name__ == '__main__':
s_time = time.time()
i = 0
while i < 100:
i += 1
runOnce(1,i)
print('一共用时:', time.time() - s_time)
很简单的一段循环代码,结果毫无意外
image.png
现在改用多线程执行
import threading #Python多线程模块,利用它启动多线程
import time
def run(sec):
print('%s 线程开始了!' % threading.current_thread().name)
time.sleep(sec)
print('%s 线程结束了!' % threading.current_thread().name)
if __name__ == '__main__':
s_time = time.time()
# 产生100个线程
i = 0
array = []
while i < 100:
i += 1
# 创建thread对象,target传入线程执行的函数,args传参数
t = threading.Thread(target=run, args=(1,))
array.append(t)
# 使用start()开始执行每一个线程
for i in array:
i.start()
# 等待主线程
for i in array:
i.join()
print('主线程执行结束', threading.current_thread().name)
print('一共用时:', time.time()-s_time)
执行结果
image.png
同样是循环100次进行打印,但是多线程情况下可以发现打印是无序的(异步,无需等待上一个执行完毕后再执行下一个),而且只使用了1秒钟多一点,假想下假如你同时发送一百条短信,是等待100多秒好一点还是1秒好点?好明显在这中情况下多线程的速度优势就很明显了








网友评论