zoukankan      html  css  js  c++  java
  • 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
    版权声明:本文为博主原创文章,转载请附上博文链接!

  • 相关阅读:
    GTest交流与经验总结
    linux i2c驱动架构-dm368 i2c驱动分析
    在不同编译环境中如何使用sleep()函数
    Android应用之基本的组件(一)
    Java Arrays Tutorial (3)
    ASP.NET中操作SQL数据库
    安卓开发06:布局-线性布局 LinearLayout
    在开发 ExtJS 应用程序常犯的 10 个错误
    每天4个linux命令--步骤一
    获取CPU序列号
  • 原文地址:https://www.cnblogs.com/sunmoon1993/p/10036465.html
Copyright © 2011-2022 走看看