第三十六天进程的·进阶:

1进程的一个例子:

from multiprocessing import Process
def func():
    print(12345)
if __name__=='__main__':
    print('主进程')
    p=Process(target=func)  #创建了一个进程的类
    p.start()  #执行了进程列方法 ,即启动了一个子进程,操作系统中创建了一个新进程
                #执行新进程中的代码
    print('*'*10)
结果为
主进程
**********
12345
View Code

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
View Code

  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
View Code

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('主进程执行结束')
结果为
主进程
主进程执行结束
*************
**************
View Code

从程序的执行效果来看,先打印的是主进程和子进程的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('主进程执行结束')
结果为
主进程
*************
**************
主进程执行结束
View Code

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('主进程执行结束')
View Code

  改进后的方法:

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('主进程执行结束')
View Code

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'])]
View Code

文件程序的讲解:

 

 

 

 

 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
View Code

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('主进程')
View Code

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
View Code

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
View Code

 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()
View Code

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()
View Code

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('主程序还在进行')
View Code

从结果我们可以发现主进程结束之后,子进程还在不停的进行着。

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
这个子进程还在执行着
主程序还在进行
这个子进程还在执行着
这个子进程还在执行着
主程序还在进行
这个子进程还在执行着
这个子进程还在执行着
主程序还在进行
这个子进程还在执行着
这个子进程还在执行着
主程序还在进行
这个子进程还在执行着
这个子进程还在执行着
主程序还在进行
View Code

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
View Code

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('主进程结束')
View Code

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查看
View Code

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()
View Code

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()
View Code

 

 

 

 

 

  

posted @ 2020-03-12 17:35  chown  阅读(148)  评论(0编辑  收藏  举报