Python进程

线程是最小的执行单元,而进程至少由一个线程组成。

1.单个子进程

multiprocessing模块提供了一个Process类来代表一个进程对象。

代码:

def run_child(name):
    for i in range(4):
        print('我是子进程 {} : {}'.format(name,os.getpid()))        
if __name__=='__main__':
    print('父进程是 {}'.format(os.getpid()))
    p=Process(target=run_child,args=('banana',))#创建一个Process实例
    print('子进程接下来就要执行了...')
    p.start()   #启动子进程
    p.join()    #等待子进程结束后继续往下运行
    print('所有进程都执行完了.')

输出:

2.多个子进程

用进程池的方式创建多个子进程。

(1)apply:

是阻塞的,等待当前子进程执行完毕后,才执行下一个进程。

流程:主进程先开始运行,碰到子进程后,操作系统立刻切换到子进程,等待所有子进程运行完毕。然后再切换到主进程,运行剩余的部分。

(2)apply_async:

是异步非阻塞的,不用等待当前子进程执行完毕,根据系统调度来进行进程切换。

流程:主进程先开始运行,碰到子进程后,主进程会"视而不见",先执行完自己的再说。直到操作系统切换进程的时候,再交给子进程运行。(由于代码少,往往主进程会执行完毕。)

p.join():   

用来阻塞主进程,如果不阻塞主进程,会导致主进程往下运行到结束。

调用join()之前必须先调用close(),否则会报错。

代码:
from multiprocessing import Pool
import os,time

#在进程池执行的函数
def run_child(name):
    print('我是子进程 {} {}'.format(name,os.getpid()))
    start=time.time()
    time.sleep(1)
    end=time.time()
    print('子进程 {0} 运行了 {1:.2f} 秒.'.format(name,(end-start)))

if __name__=='__main__':
    print('父进程是 {}'.format(os.getpid()))
    p=Pool(4)   #进程池最大运行数
    for i in range(6):
        #p.apply(run_child,args=(i,))    #阻塞
        p.apply_async(run_child,args=(i,)) #非阻塞
    print('先等等吧...')
    p.close()   #关闭进程池,使其不在接受新的任务
    p.join()    #用来阻塞主进程
    print('所有进程都执行完了.')

非阻塞输出:

阻塞输出:

3.运行外部命令

subprocess.call(command)方法

可以用于执行一个外部命令,该方法不能返回执行的结果,只能返回执行的状态码:成功(0)或错误(非0)。

command可以是列表,也可以是字符串,作字符串时需要用原生的shell来执行。

代码:

import subprocess
print('启动notepad...')
n=subprocess.call(['notepad'])
print('code:',n)

#subprocess.check_call()处理异常
try:
    subprocess.check_call("notepad1",shell=True)
except subprocess.CalledProcessError as e:
    print("异常是:",e)

输出:

4.进程的通信

mutiprocessing模块提供的Queue和Pipe可以实现进程间的通信。

(1)Queue

代码:

from multiprocessing import Process,Queue
import os
def shop(q):
    print('我要购买水果的进程 {}.'.format(os.getpid()))
    fruit_list=['banana','apple','orange']
    q.put(fruit_list)
    
def look(q):
    print('我要看看购物车的进程 {}.'.format(os.getpid()))
    value=q.get()
    print('原来我挑选了 {}'.format(value))

if __name__ == '__main__':
    #父进程创建Queue,并传给各子进程
    q=Queue()
    #两个子进程
    p1=Process(target=shop,args=(q,))
    p2=Process(target=look,args=(q,))
    p1.start()
    p2.start()
    p1.join()
    print('p1结束了!')
    p2.join()
    print('p2结束了!')

输出:

(2)Pipe管道

可以是单向或双向(默认)。

代码:

from multiprocessing import Process,Pipe
import os
def client(p):
    str='hello,小明...'
    p.send(str)
    print('to service:',str)
def service(p):
    print('from client:',p.recv())
if __name__=='__main__':
    print('父进程是 {}'.format(os.getpid()))
    p=Pipe()
    p1=Process(target=client,args=(p[0],))
    p2=Process(target=service,args=(p[1],))
    p1.start()
    p2.start()
    p1.join()
    p2.join()
    print('所有进程都结束了!')

输出:



猜你喜欢

转载自blog.csdn.net/southwind0/article/details/80298442
今日推荐