作者简介:
Horea,柠檬班全程班第30期python自动化2期学员。目前在上海从事软件测试工作,年薪32.4万。
从测试小白一路进阶,在3年内成为测试经理。她将在柠檬班上课所学到的内容及自己的学习感悟整理成了博客,汇合成一个完整的学习笔记。
今天,是我们转载她的博客笔记的第二天,内容是关于进程线程协程的下篇。
关于进程线程协程上篇笔记,请戳链接↓↓↓
年薪32.4万的学霸笔记连载(一)——进程线程协程(上)
04进程进程是操作系统资源分配的基本单位,一个进程中可以有多个线程线程:线程是操作系统任务调度的基本单位
多个进程可以同时进行每个进程之间资源是独立的
进程和线程对比
功能进程能够完成多任务,比如在一台电脑上能够同时运行多个软件线程能够完成多任务,比如一个qq中的多个聊天窗口定义的不同
进程是系统进行资源分配和调度的一个独立单位
线程是进程的一个实体,是CPU调度和任务分派的基本单位,它比进程更小的能独立运行的基本单位。
线程自己基本上不拥有系统资源,只拥有一点在运行中必不可少的资源,但是它可与同属一个进程的其他线程共享进程所拥有的全部资源
python中同一个进程中的线程是没办法并行的(GIL),进程是可以并行的,不同进程中的线程也是可以并行的
frommultiprocessingimportProcessdefwork1(name):foriinrange(20):print(f"{name}在浇花")defwork2(name):foriinrange(20):print(f"{name}在做饭")t=Process(target=work1,args=("jerry",))t2=Process(target=work2,args=("jerry",))t.start()t2.start()t.join()t2.join()
多进程不可共享全局变量
Python多进程默认不能共享全局变量,因为进程的资源是独立的
主进程与子进程是并发执行的,进程之间默认是不能共享全局变量的(子进程不能改变主进程中全局变量的值)frommultiprocessingimportQueue,Processn=defwork1():globalnforiinrange():n+=1print("work1执行完后n",n)defwork2():globalnforiinrange():n+=1print("work2执行完后n",n)t=Process(target=work1)t2=Process(target=work2)t.start()t2.start()t.join()t2.join()print("两个子进程执行完后主进程中n的值:",n)=============执行结果=================work1执行完后n:50work2执行完后n:两个子进程执行完后主进程中n的值:
多进程之间通信
进程之间通信:使用队列
multiprocessing.Queue:可以多个进程之间共用(通用)跨进程通讯队列要在主进程中创建当成参数传给子进程
queue.Queue模块只能在一个进程中使用一个进程中多个线程使用
frommultiprocessingimportQueue,Processdefwork1(q):#要把队列当成参数传进来foriinrange(0):n=q.get()n+=1q.put(n)print("work1n执行后的值",q.get())defwork2(q):#要把队列当成参数传进来foriinrange(0):n=q.get()n+=1q.put(n)print("work2n执行后的值",q.get())if__name__==__main__:#队列要在主进程中创建当成参数传给子进程q=Queue()q.put()t=Process(target=work1,args=(q,))t1=Process(target=work2,args=(q,))t.start()t1.start()t.join()t1.join()print("两个子进程执行结束后,主进程打印的n",q.get())=============执行结果=================work1n执行后的值work2n执行后的值10两个子进程执行结束后,主进程打印的n10
通过继承自定义进程类
frommultiprocessingimportProcess,Queueimportrequests"""创建4个进程发送个请求"""classMyprocess(Process):def__init__(self,q):super().__init__()#重写后需要调用父类init创建线程self.q=qdefrun(self):#方法名必须是run()通过start()来调起"""线程执行的任务函数:return:"""whilenotself.q.empty():#当队列中不为空时即进行下面操作url=self.q.get()requests.get(url)print(f"发送请求:{url}")#打印进程idprint(f"{self.pid}")#创建队列q=Queue()#创建一个个url放进队列里foruinrange():url=