Python并发机制的实现(一)——多进程

Python并发机制的实现(一) —— 多进程
Unix/Linux系统调用实现多进程(Windows系统不支持)
Unix/Linux操作系统提供了一个fork()系统调用,它非常特殊。普通的函数调用,调用一次,返回一次,但是fork()调用一次,返回两次,因为操作系统自动把当前进程(称为父进程)复制了一份(称为子进程),然后,分别在父进程和子进程内返回。

子进程永远返回0,而父进程返回子进程的ID。这样做的理由是,一个父进程可以fork出很多子进程,所以,父进程要记下每个子进程的ID,而子进程只需要调用getppid()就可以拿到父进程的ID。

#coding=utf-8
import os
import time

pid = os.fork()

#子进程
if pid==0:
while True:
print "child process {}".format(os.getpid())
time.sleep(2)
#父进程
else:
while True:
print "parent process {}".format(os.getppid())
time.sleep(2)

运行结果:

parent process 3614
child process 3761
child process 3761
parent process 3614
child process 3761
parent process 3614
^\退出 (核心已转储)

有了fork调用,一个进程在接到新任务时就可以复制出一个子进程来处理新任务,常见的Apache服务器就是由父进程监听端口,每当有新的http请求时,就fork出子进程来处理新的http请求。

multiprocessing模块
使用multiprocessing模块可以兼容windows操作系统,具体可见源码中python2.7中multiprocessing下的forking.py

#coding=utf-8
import time
import os
from multiprocessing import Process

def p1():
while True:
for i in range(5):
print 'pro1' + ' ' + str(os.getpid())
time.sleep(2)

def p2(name):
while True:
for i in range(5):
print name + ' ' + str(os.getpid())
time.sleep(2)

pro1 = Process()
pro2 = Process(target=p2, args=("pro2",))
#重写run函数为p1
pro1.run = p1
pro2.start()
pro2.start()
pro1.join()
pro2.join()

!注意其中的run函数,在python2.7multiprocessing模块中的源码为

def run(self):
'''
Method to be run in sub-process; can be overridden in sub-class
'''
#如果参数中传入目标函数则运行目标函数
if self._target:
self._target(*self._args, **self._kwargs)

分析源码可知创建进程实例后调用start方法启动线程通过一系列异常检测后将自动调用run方法

join方法是用来等待指定子进程的结束,再结束主进程即父进程,避免僵尸进程的产生

Pool模块(进程池)
Pool可以提供指定数量的进程,供用户调用,当有新的请求提交到pool中时,如果池还没有满,那么就会创建一个新的进程用来执行该请求;但如果池中的进程数已经达到规定最大值,那么该请求就会等待,直到池中有进程结束,才会创建新的进程来它.进程池可以让你跑满多核CPU,而且使用方法非常简单.

#coding=utf-8

from multiprocessing import Pool
import time

def f(x):
for i in range(10):
print i,'-----------',x
time.sleep(1)

def main():
#控制进程池的大小为4个进程(可以自行改动测试)
pool = Pool(processes=4)
for x in range(10):
#添加进程入进程池,注意加"_async",apply为阻塞版本,参数分别为target和args
result = pool.apply_async(f,(x*10,))
pool.close()
pool.join()
if result.successful():
print 'successful'

if __name__ == "__main__":
main()

运行此程序发现每次最多只有四个进程并行执行,运行结果如下:

0 ----------- 0
0 ----------- 10
0 ----------- 20
0 ----------- 30
1 ----------- 0
1 ----------- 10
1 ----------- 30
1 ----------- 20
2 ----------- 0
2 ----------- 10
2 ----------- 20
2 ----------- 30
...
8 ----------- 90
8 ----------- 80
9 ----------- 80
9 ----------- 90
successful
---------------------
作者:Always0nTheWay
来源:CSDN
原文:https://blog.csdn.net/wukai_std/article/details/53268006
版权声明:本文为博主原创文章,转载请附上博文链接!

posted @ 2018-11-29 09:53  会吃键盘的小懒熊  阅读(366)  评论(0编辑  收藏  举报