第三十六天进程的·进阶:
1进程的一个例子:
from multiprocessing import Process def func(): print(12345) if __name__=='__main__': print('主进程') p=Process(target=func) #创建了一个进程的类 p.start() #执行了进程列方法 ,即启动了一个子进程,操作系统中创建了一个新进程 #执行新进程中的代码 print('*'*10) 结果为 主进程 ********** 12345
2.在操作系统中每一个程序都有对应的pid号,怎么查看主进程和子进程的pid号及父进程的pid号:
from multiprocessing import Process import os def func(): print('子进程的pid%s'%os.getpid())#查看此进程的pid print('子进程中父类的pid%s'%os.getppid()) print(12345) if __name__=='__main__': print('主进程') print('主进程的pid%s'%os.getpid()) p=Process(target=func) #创建了一个进程的类 p.start() #执行了进程列方法 ,即启动了一个子进程,操作系统中创建了一个新进程 #执行新进程中的代码 print('主进程中父类的pid%s'%os.getppid()) print('*'*10) 结果为 主进程 主进程的pid1124 主进程中父类的pid9332 ********** 子进程的pid34364 子进程中父类的pid1124 12345
tip:怎么查看操作系统中的pid:通过右击鼠标找到任务管理器,之后电机详细信息就可以找到pid了
3.怎么对进程传递参数:
from multiprocessing import Process import os def func(args,args1): print(args,args1) print(12345) if __name__=='__main__': print('主进程') p=Process(target=func,args=(123,'hello,python')) #创建了一个进程的类,所传参数必须是一个元组 # 如果只有一个元素,后面要加逗号 p.start() #执行了进程列方法 ,即启动了一个子进程,操作系统中创建了一个新进程 #执行新进程中的代码 print('*'*10) 结果为 主进程 ********** 123 hello,python 12345
4.进程的生命周期:
从现在开始,程序中就开始包含主进程和子进程两个部分,开启子进程的主进程:1.如果主进程自己的代码过长,需要等待自己的代码执行结束以后才会结束。2.如果子进程的执行时间过长,主进程在执行完自己的代码之后会等待子进程执行完毕后才会停止
5.看下面一个程序:
from multiprocessing import Process import time def func(a,b): print(a*'*') time.sleep(5) print(b*'*') if __name__=='__main__': print('主进程') p=Process(target=func,args=(13,14)) p.start() print('主进程执行结束') 结果为 主进程 主进程执行结束 ************* **************
从程序的执行效果来看,先打印的是主进程和子进程的a那一列,等5s过了之后才打印b哪一个,说明主进程和子进程是异步进行的。
6.那么怎么让子进程进行结束以后在去执行主进程:可以采用join的方法:
from multiprocessing import Process import time def func(a,b): print(a*'*') time.sleep(5) print(b*'*') if __name__=='__main__': print('主进程') p=Process(target=func,args=(13,14)) p.start() p.join()#感知一个程序的结束,将异步程序改成同步程序 print('主进程执行结束') 结果为 主进程 ************* ************** 主进程执行结束
7.如果有多个进程同时启动,那要怎么样可以做到子进程执行完成,在执行主进程
第一种方法:
from multiprocessing import Process import time def func(a): print(a*'*') time.sleep(3) print(a*'-') if __name__=='__main__': print('主进程') for i in range(10): p=Process(target=func,args=(i,)) p.start() p.join()#子进程在执行过程中是无序的,但join方法只要嗅到最后以子进程执行就会执行主程序 print('主进程执行结束')
改进后的方法:
from multiprocessing import Process import time def func(a): print(a*'*') time.sleep(3) print(a*'-') if __name__=='__main__': process_list=[] print('主进程') for i in range(10): p=Process(target=func,args=(i,)) process_list.append(p) p.start() [i.join() for i in process_list] print('主进程执行结束')
8.利用这种方法进行多个文件的写入操作:
from multiprocessing import Process import time import os def func(filename): with open(filename,'w',encoding='utf-8')as f: f.write('wonhdfjdjfkjdfj') if __name__=='__main__': process_list=[] print('主进程') for i in range(5): p=Process(target=func,args=('info%s'%i,)) process_list.append(p) p.start() [i.join() for i in process_list] print(list(os.walk('D:\python练习程序\第三十六天'))) 结果为 主进程 [('D:\\python练习程序\\第三十六天', ['.idea'], ['info0', 'info1', 'info2', 'info3', 'info4', 'practise.py', 'process1.py', 'second.py']), ('D:\\python练习程序\\第三十六天\\.idea', [], ['.name', 'encodings.xml', 'misc.xml', 'modules.xml', 'workspace.xml', '第三十六天.iml'])]
文件程序的讲解:
9.总结 同步:500个进程每个进程执行0.1s总共·执行50s
异步:500个进程,每个进程执行0-1s总共执行0.1s
10使用类来写进程:必须要有run方法:
from multiprocessing import Process import os def func(args,args2,args3): print(args) print('子进程',os.getpid()) print('子进程当中的父进程',os.getppid()) if __name__=='__main__': p=Process(target=func,args=(123,444,555)) p.start() print('主进程') print('父进程',os.getpid()) print('父进程当中的父进程',os.getppid()) 结果为 主进程 主进程 hello,python hello,python
11.10的运行原理是:
from multiprocessing import Process class Myprocess(Process): def run(self): print('hello,python') def start(self): self.run() if __name__=='__main__': print('主进程') p1=Myprocess() p1.start() #为什么执行start就执行定义类中的run那? p2=Myprocess() p2.start() print('主进程')
12.怎么在自己定义的类中传递参数:
from multiprocessing import Process class Myprocess(Process): def __init__(self,agg): super().__init__() self.agg=agg def run(self): print(self.agg) print(self.pid) if __name__=='__main__': print('主进程') p1=Myprocess('alex') p1.start() #为什么执行start就执行定义类中的run那? p2=Myprocess('egg') p2.start() print('主进程') 结果为 主进程 主进程 alex 32244 egg 18652
13.每个进程之间的数据都是相护独立,没有任何联系:
from multiprocessing import Process def func(): global a #声明一个全局变量 a=0 #定义一个新的变量 print('子进程a:%s'%a) if __name__ =='__main__': a=100 #定义一个新的全局变量 p=Process(target=func) p.start() print('主进程a:%s'%a) 结果为 主进程a:100 子进程a:0
14.用多进程写服务端和客户端:
server
import socket from multiprocessing import Process def func(conn): msg=('你好').encode('utf-8') conn.send(msg) ret=conn.recv(1024).decode('utf-8') print(ret) conn.close() if __name__=='__main__': sk=socket.socket() sk.bind(('127.0.0.1',8080)) sk.listen() while True: conn,addr=sk.accept() p=Process(target=func,args=(conn,)) p.start() sk.close()
client
import socket sk=socket.socket() sk.connect(('127.0.0.1',8080)) ret=sk.recv(1024).decode('utf-8') print(ret) msg=input('>>>').encode('utf-8') sk.send(msg) sk.close()
15.看下面程序的结果,和现象:
from multiprocessing import Process import time def func(): time.sleep(0.2) print('这个子进程还在执行着') if __name__ =='__main__': while True: Process(target=func).start() time.sleep(1) print('主程序还在进行')
从结果我们可以发现主进程结束之后,子进程还在不停的进行着。
16.怎么解决上述的问题,可以采用守护进程的方法:即设置daemon=True
from multiprocessing import Process import time def func(): while True: time.sleep(0.5) print('这个子进程还在执行着') if __name__ =='__main__': i=0 p= Process(target=func) p.daemon=True p.start() while i<5: time.sleep(1) print('主程序还在进行') i+=1 执行结果为 C:\pycharm\python.exe D:/python练习程序/第三十六天/processs2.py 这个子进程还在执行着 主程序还在进行 这个子进程还在执行着 这个子进程还在执行着 主程序还在进行 这个子进程还在执行着 这个子进程还在执行着 主程序还在进行 这个子进程还在执行着 这个子进程还在执行着 主程序还在进行 这个子进程还在执行着 这个子进程还在执行着 主程序还在进行
17.守护进程会随着主进程的代码执行完毕而结束。
18看下面一个程序:
def func2(): time.sleep(8) print('hello') if __name__ =='__main__': i=0 p= Process(target=func) p.daemon=True p.start() Process(target=func2).start() while i<5: time.sleep(1) print('主程序还在进行') i+=1
19.在进行文件写入的时候,数据的类型必须是字符串,否则会报错:
19.结束一个进程terminate
from multiprocessing import Process import time def func(): while True: time.sleep(0.4) print('我还活着') def func2(): time.sleep(9) print('执行结束') if __name__=='__main__': p1=Process(target=func) p1.daemon=True #设置此进程为守护进程,主进程结束子进程结束 p1.start() p2=Process(target=func2) p2.start() p2.terminate() #将此进程结束 time.sleep(3) print('主进程结束')
20.火车票多人查票系统:
import json from multiprocessing import Process def show (filename,i): with open(filename,encoding='utf-8')as f: ret=json.load(f) print('余票剩余%s,%s查看'%(ret['ticket'],i)) if __name__=='__main__': for i in range(10): p=Process(target=show,args=('ticket',i)) p.start() 结果为 余票剩余1,3查看 余票剩余1,1查看 余票剩余1,0查看 余票剩余1,4查看 余票剩余1,8查看 余票剩余1,6查看 余票剩余1,5查看 余票剩余1,2查看 余票剩余1,9查看 余票剩余1,7查看
21.火车票购买系统:
import json from multiprocessing import Process def buy(filename,i): with open(filename,encoding='utf-8')as f: ret=json.load(f) if ret['ticket']>0: ret['ticket']-=1 print('\033[32m%s买到票了\033[0m'%i) with open(filename,'w')as f: json.dump(ret,f) else: print('\033[32m%s没有买到票了\033[0m'%i) if __name__=='__main__': for i in range(10): p=Process(target=buy,args=('ticket',i)) p.start()
22.锁的概念:当有多个进程进入一个函数时,同一时间,只能有一个进程进入,当此进程执行结束以后,才允许下个进程进程进入里面进行程序的执行
常用于数据的修改和重要的
程序如下:
import json from multiprocessing import Process,Lock def buy(filename,i,lock): lock.acquire() #拿唯一一把钥匙,并在把门锁上防止其他进程进入 with open(filename,encoding='utf-8')as f: ret=json.load(f) if ret['ticket']>0: ret['ticket']-=1 print('\033[32m%s买到票了\033[0m'%i) else: print('\033[32m%s没有买到票了\033[0m'%i) with open(filename,'w')as f: json.dump(ret,f) lock.release() #进程走完,把钥匙归还 if __name__=='__main__': lock=Lock() #进行锁的实例化 for i in range(10): p=Process(target=buy,args=('ticket',i,lock)) p.start()