python之多进程

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

def run_child(name):
	print("this is a child process %s (%s)"%(name,os.getpid()))
if __name__=="__main__":
	p=Process(target=run_child,args=('test',))
	print("Parent Process %s"%(os.getpid()))
	p.start()
	p.join()
	print("child process end")

运行结果:

Parent Process 73984
this is a child process test (76768)
child process end

创建子进程时,只需要传入一个执行函数和函数的参数,创建一个Process实列,用start()方法启动,join()方法可以等待子进程 结束后再继续往下运行(通常用于进程的同步)

Pool启动大量的子进程,用进程池的方式批量创建子进程

from  multiprocessing import Pool
def muti_task(name):
	print("run task %s %s"(os.getpid(),name))
if __name__=="__main__":
	print("parent process %s"%(os.getpid))
	p=Pool(4)
	for i in range(4):
		p.apply_async(muti_task,args=(i,))
	p.close()
	p.join()
	print("all process done.")

运行结果:

parent process 78272
run task 74240 0
run task 74240 1
run task 74240 2
run task 74240 3
all process done.

对Pool对象调用join()方法会等待所有子进程执行完毕,调用join()之前必须先调用close(),调用close()之后就不能继续添加新的process了。
task是否立即开始运行取决于pool默认的大小,最多同时执行大小限制为4,如果p=Pool(5)则同时跑5个进程,但是由于Pool默认大小时CPU的核数,比如我当前电脑是8核,要设置9个进程才看出区别:
在这里插入图片描述

def muti_task(name):
	print("run task %s %s"%(os.getpid(),name))
	time.sleep(0.1)
	print("name %s"%(name))
if __name__=="__main__":
	print("parent process %s"%(os.getpid()))
	p=Pool(8)
	for i in range(9):
		p.apply_async(muti_task,args=(i,))
	p.close()
	p.join()
	print("all process done.")

运行结果:

parent process 13316
run task 1080 0
run task 4020 1
run task 11728 2
run task 1720 3
run task 19892 4
run task 5004 5
run task 16828 6
run task 19868 7
name 0
run task 1080 8
name 1
name 2
name 3
name 4
name 5
name 6
name 7
name 8
all process done.

子进程
很多时候,子进程并不是本身,而是外部进程。创建了子进程后需要控制子进程的输入和输出。
subprocess模块可以让我们非常方便的启动一个子进程,然后控制输入输出。

C:\Users\18566>nslookup www.baidu.com
0.e.0.4.2.ip6.arpa      nameserver = ns.cta.net.cn
0.e.0.4.2.ip6.arpa      nameserver = dns.cta.net.cn
ns.cta.net.cn   internet address = 61.128.192.77
dns.cta.net.cn  internet address = 61.128.128.77
ns.cta.net.cn   AAAA IPv6 address = 240e:47:3:702::2
dns.cta.net.cn  AAAA IPv6 address = 240e:47:3:703::2
(root)  ??? unknown type 41 ???
服务器:  UnKnown
Address:  240e:1f:1::1

非权威应答:
名称:    www.a.shifen.com
Addresses:  14.215.177.38
          14.215.177.39
Aliases:  www.baidu.com

代码 :

import subprocess
print("$ nslookup  www.baidu.com")
r=subprocess.call(['nslookup','www.baidu.com'])
print('exit code:',r)

如果子进程需要输入,则可以通过communicate()方法输入:

import subprocess
print("$nslookup")
p=subprocess.Popen(['nslookup'],stdin=subprocess.PIPE,stdout=subprocess.PIPE,stderr=subprocess.PIPE)
output,err=p.communicate(b'set q=mx\nbaidu.com\nexit\n')
print(output.decode('gbk'))
print('Exit code:',p.returncode)

相当于在命令行输入nslookup
然后手动输入:

set q=mx
baidu.com
exit

进程间通信
Process之间需要互相通信,操作系统提供了很多机制来实现进程间的通信,python的multiprocssing模块包装了底层的机制,提供了Queue\Pipes等多种方式交换数据。
在父进程创建2个子进程,一个往里面写数据一个从Queue读数据。

from multiprocessing import Process,Queue
import os,time,random
def write(q):
    print("Process to write: %s"%(os.getpid()))
    for v in [11,23,34,56]:
        print("PUT %d to queue"%v)
        q.put(v)
        time.sleep(random.random())
def read(q):
    print("Process to read %s"%os.getpid())
    while True:
        vaule=q.get(True)
        print("get %d from queue"%vaule)
if __name__=="__main__":
    q=Queue()
    pw=Process(target=write,args=(q,))
    pr=Process(target=read,args=(q,))
    pw.start()
    pr.start()
    pw.join()
    pr.terminate()
运行结果:
    Process to write: 20388
PUT 11 to queue
Process to read 20240
get 11 from queue
PUT 23 to queue
get 23 from queue
PUT 34 to queue
get 34 from queue
PUT 56 to queue
get 56 from queue

其中pr进程是死循环无法等待结束,所以强行结束 pr.terminate()

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值