第八篇 并发(进程和线程)
Python里执行并发有进程和线程两个,分布使用 threading 和multiprocessing 两个库,一般用的是这两个库里的Thread和Process
from threading import Thread # 线程 : 同时运行 from multiprocessing import Process # 进程
进程和线程的使用场景:
1. 一般在有大量的数据(耗时)操作的时候,会用到线程和进程
2.python里要优先用进程,因为Python里的线程有个自带的bug,全局解释器锁
示例1:有大猫和小猫睡觉的两个模拟耗时的操作,如果不用并发,执行效果就是从上到下顺序 串行执行的
from threading import Thread # 线程 : 同时运行 import time, random # 模拟耗时操作:大猫和小猫睡觉 def daMaoSleep(n): print("大猫开始睡觉了,它要睡{}秒".format(n) ) time.sleep(n) print("现在大猫睡醒了") def xiaoMaoSleep(n): print("小猫开始睡觉了,它要睡{}秒".format(n) ) time.sleep(n) print("现在小猫睡醒了") if __name__ == '__main__': # 不适用线程和进程,是顺序串行的 n_da = random.randint(3,5) n_xiao = random.randint(3,6) # 使用线程库进行并行,注意target是函数名,args是参数,参数必须是元组 # target=传参是要运行的函数,args=(n,) args是个元组,如果只有一个参数,要带逗号的 # 使用线程库进行并行,注意target是函数名,args是参数,参数必须是元组 # 执行大猫睡觉 thread = Thread(target=daMaoSleep,args=(n_da,)) thread.start() # 执行小猫睡觉 thread = Thread(target=xiaoMaoSleep,args=(n_xiao,)) thread.start() # 输出 大猫开始睡觉了,它要睡4秒 小猫开始睡觉了,它要睡3秒 现在小猫睡醒了 现在大猫睡醒了
示例2:如果想让大猫和小猫同时开始睡觉,怎么操作呢?
这里用线程的方式实现并发演示
from multiprocessing import Process # 进程 import time, random # 模拟耗时操作:大猫和小猫睡觉 def daMaoSleep(n): print("大猫开始睡觉了,它要睡{}秒".format(n) ) time.sleep(n) print("现在大猫睡醒了") def xiaoMaoSleep(n): print("小猫开始睡觉了,它要睡{}秒".format(n) ) time.sleep(n) print("现在小猫睡醒了") if __name__ == '__main__': n_da = random.randint(3,5) n_xiao = random.randint(3,6) # 使用进程库进行并行,注意target是函数名,args是参数,参数必须是元组 # target=传参是要运行的函数,args=(n,) args是个元组,如果只有一个参数,要带逗号的 # 使用进程库进行并行,注意target是函数名,args是参数,参数必须是元组 # 执行大猫睡觉 process = Process(target=daMaoSleep,args=(n_da,)) process.start() # 执行小猫睡觉 process = Process(target=xiaoMaoSleep,args=(n_xiao,)) process.start() # 输出 大猫开始睡觉了,它要睡4秒 小猫开始睡觉了,它要睡3秒 现在小猫睡醒了 现在大猫睡醒了
注意避免踩坑:进程和线程一定要写在 if __name__ == '__main__' 里面的,否则会报错
进程与线程的区别:
什么是进程,什么是线程
系统要做一件事,运行一个任务,所有运行的任务通常就是一个程序;
每个运行中的程序就是一个进程,这一点在任务管理器上面可以形象的看到。
当一个程序运行时,内部可能会包含多个顺序执行流,每个顺序执行流就是一个线程。
关于进程的特性
独立性:进程是系统中独立存在的实体,它可以拥有自己独立的资源,每个进程都拥有自己私有的地址空间。在没有经过进程本身运行的情况下是不能访问其中的内容的。
动态性:进程与程序的区别在于,程序是静态的,进程是动态的。程序只是一个静态的指令集合,而进程是一个正在系统中运行的指令集合。有了时间的概念,如生命周期;
并发性:进程之间,交替着执行。
线程,一个顺序执行流;
它是进程的组成部分,一个进程可以有多个线程。
关于线程的特性,或是它的优势
1、进程之间不能共享内存,单线程之间共享内存非常的容易
2、系统创建进程需要为该进程重新分配系统资源,但创建线程的代价很小。因此多线程的实现多任务并发比多进程实现并发的效率高
3、java语言内置多线程功能支持,而不是单纯的作为底层操作系统的调度方式
总结:
一个程序运行至少一个进程,一个进程里面至少包含一个线程,线程是进程的组成部分。
线程相对于进程而言,很强大了,做到了资源的共享,资源的损耗降低,人为的手工控制程序的运行。
多进程通信的方式有哪些?
1. 共享内存
2. 信号
3. 信号量
4. 管道
5. socket通信
多线程的通信方式有哪些?
因为线程运作在进程里里面,所以多线程的通信方式也就是多线程的通信方式
不过,总的来说,目前进程和线程已经过时了,当前主流的处理方式都用消息队列实现