Python多进程multiprocessing的简单介绍

通过multiprocessing的Process类,我们可以创建一个Process对象。Process类类似于Python线程中的threading.Thread,可以通过这里了解一下。

直接上代码:

# encoding=utf8

import os
from multiprocessing import Process

s = '\033[31;42m'
e = '\033[0m'

def grandson(parent):
	print "--- %ssubprocess %s's son: %s is running%s" % (s, parent, os.getpid(), e)

def run(num):
	pid = os.getpid()
	print '- Child %s process %s is running' % (num, pid)
	p = Process(target=grandson, args=(pid, ))
	p.start()
	p.join()

if __name__ == '__main__':
	print 'Parent process %s is running' % os.getpid()
	for i in range(3):
		p = Process(target=run, args=(i,))
		p.start()
		p.join()
	print 'Parent is end'

运行结果:


上面的例子中,主进程创建了3个子进程,每个子进程又各自创建了一个子进程(孙子进程)。

1.说明

1.在向Process传入args参数的时候要使用元组,且传入的参数只有一个的时候要写成:(i,),否则会报错;

2.start方法:启动子进程;

3.join方法:子进程使用join可以让主进程进入等待(阻塞主进程),子进程全部结束后,主进程才继续执行。

2.设置守护进程

        将子进程的daemon值设置为True,这时候子进程会随着主进程结束而结束,需要注意的是,设置守护进程应该在start()执行之前,否则会报错;同时,如果子进程设置了守护进程,子进程就不能再创建自己的子进程了。而且,如果想要使用守护进程,子进程就不要再调用join()函数了,否则p.daemon = True会失效(子进程依然会阻塞主进程)。

代码示例:

# encoding=utf8

import os
from multiprocessing import Process

s = '\033[31;42m'
e = '\033[0m'

def grandson(parent):
	print "--- %ssubprocess %s's son: %s is running%s" % (s, parent, os.getpid(), e)

def run(num):
	pid = os.getpid()
	print '- Child %s process %s is running' % (num, pid)
	p = Process(target=grandson, args=(pid, ))
	p.start()
	p.join()

if __name__ == '__main__':
	print 'Parent process %s is running' % os.getpid()
	for i in range(3):
		p = Process(target=run, args=(i,))
		p.daemon = True
		p.start()
	print 'Parent is end'

运行结果:

Parent process 51904 is running
Parent is end

通过结果可以知道,子进程设置守护进程后,主进程结束的时候,子进程也就结束了。

3.进程间资源不共享

进程与线程不同,进程没有任何共享状态,进程修改的数据,改动仅限于该进程内,不会影响父进程内的资源。示例:

# encoding=utf8

from multiprocessing import Process
from threading import Thread

n = 100

def work(name):
	global n
	n = 0
	print '当前%s内的n值为: %s' % (name, n)

if __name__ == '__main__':
	p = Process(target=work, args=('子进程',))
	p.start()
	p.join()
	print '主进程n值为: ',n
	print '-' * 33
	t = Thread(target=work, args=('子线程',))
	t.start()
	t.join()
	print '主进程n值为: ',n

运行结果:

当前子进程内的n值为: 0
主进程n值为:  100
---------------------------------
当前子线程内的n值为: 0
主进程n值为:  0

上面的例子可以表明,子进程与主进程之间没有共享资源,但是子线程是可以调用和影响父进程资源的。

最后,推荐一篇相关博文:https://www.cnblogs.com/linhaifeng/articles/7428874.html。

----- 2018年4月24日 更新 -----

今天通过官方文档看到其他方法,可以实现主进程和子进程间的资源共享,一种是使用multiprocessing的共享对象(共享内存)Value和Array来实现,它们是可以保证进程安全和线程安全的:

# coding:utf-8

from multiprocessing import Process, Value, Array

def f(n, a):
	n.value = 1.23456
	for i in range(len(a)):
		a[i] = -a[i]

def main():
	num = Value('d', 0.0)        # d表示双精度浮点型
	arr = Array('i', range(10))  # i表示带符号的整型

	p = Process(target=f, args=(num, arr))
	p.start()
	p.join()

	print 'num: ', num.value
	print 'arr: ', arr[:]

if __name__ == '__main__':
	main()

运行结果:

num:  1.23456
arr:  [0, -1, -2, -3, -4, -5, -6, -7, -8, -9]

另一种就是使用服务器进程Manager:

# coding:utf-8

from multiprocessing import Process, Manager

def f(d, l):
	d[1] = '1'
	d['2'] = 2
	d[0.25] = None
	l.reverse()

def main():
	manager = Manager()

	d = manager.dict()
	l = manager.list(range(10))
	p = Process(target=f, args=(d, l))
	p.start()
	p.join()

	print '--- d: ', d
	print '--- l: ', l

if __name__ == '__main__':
	main()

运行结果:

--- d:  {0.25: None, 1: '1', '2': 2}
--- l:  [9, 8, 7, 6, 5, 4, 3, 2, 1, 0]

manager对象支持的数据类型有:list, dict, Namespace, Lock, RLock, Semaphore, BoundedSemaphore, Condition, Event, Queue, Value and Array。

Manager比Value和Array使用起来更灵活,因为它支持更多类型的对象。一个manager对象可以通过网络接口共享给不同机器上的进程。当然,Manager使用起来可能会比共享内存慢。

  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值