Python公开课 - 多进程使用

前言

大家使用计算机,会天天和进程打交道,例如打开一个chrome浏览器去上网看新闻,在windows的任务管理器里面就会看到有google chrome这个进程。

按书面语来解释进程是计算机中的程序关于某数据集合上的一次运行活动,是系统进行资源分配和调度的基本单位,是操作系统结构的基础。

这里主要有两个概念:

  1. 进程是一个实体。每一个进程都有它自己的地址空间,一般情况下,包括文本区域(text region)、数据区域(data region)和堆栈(stack region)。文本区域存储处理器执行的代码;数据区域存储变量和进程执行期间使用的动态分配的内存;堆栈区域存储着活动过程调用的指令和本地变量。
  2. 进程是一个“执行中的程序”。程序是一个没有生命的实体,只有处理器赋予程序生命时(操作系统执行之),它才能成为一个活动的实体。

多进程使用场景

在代码开发中,我们也会以多进程的方式来提供程序的并发性,提高执行效率,另外在有些情况下,多进程架构也可以更保证程序更安全健壮,例如谷歌浏览器:

Google Chrome将插件或者网络应用放在与浏览器本身不同的进程中。在一个渲染引擎中的崩溃并不会影响浏览器本身或是其他网络应用。这意味着操作系统可以并发的运行网络应用来提高响应速度,如果一个特定的网络应用程序或是插件停止响应时浏览器本身并不会被死锁。

Python中多进程使用

linux下可使用 fork 函数

import os

print('Process (%s) start...' % os.getpid())
pid = os.fork()
if pid==0:
    print('I am child process (%s) and my parent is %s.' % (os.getpid(), os.getppid()))
    os._exit(1)
else:
    print('I (%s) just created a child process (%s).' % (os.getpid(), pid))


输出:
Process (17601) start...
I (17601) just created a child process (17602).
I am child process (17602) and my parent is 1.

一个fork()属于系统调用,它比较特殊。调用一次,返回两次,因为操作系统自动把当前进程和子进程进行返回。子进程永远返回0,而父进程返回子进程的ID。

使用 multiprocessing

from multiprocessing import Process
import os
import time

def run_proc(name):
    time.sleep(3)
    print ('Run child process %s (%s)...' % (name, os.getpid()))

if __name__=='__main__':
    print ('Parent process %s.' % os.getpid())
    processes = []
    for i in range(5):
        p = Process(target=run_proc, args=('test',))
        print ('Process will start.')
        p.start()
        processes.append(p)

    for p in processes:
        p.join()
    print ('Process end.')


输出:
Parent process 18259.
Process will start.
Process will start.
Process will start.
Process will start.
Process will start.
Run child process test (18262)...
Run child process test (18261)...
Run child process test (18263)...
Run child process test (18260)...
Run child process test (18264)...
Process end.

创建子进程时,只需要传入一个执行函数和函数的参数,创建一个Process实例,用start()方法启动,这样创建进程比fork()还要简单。

join()方法可以等待子进程结束后再继续往下运行,通常用于进程间的同步。

进程池

如果资源有限,一般会进行池化处理,这里的感念与线程池、内存池其实是一样的。

如果要启动大量的子进程,可以用进程池的方式批量创建子进程。

使用 multiprocessing.Pool 非阻塞

import multiprocessing
import time

def func(msg):
    print("msg:", msg)
    time.sleep(3)
    print("end")

if __name__ == "__main__":
    pool = multiprocessing.Pool(processes = 3)
    for i in range(3):
        msg = "hello %d" %(i)
        pool.apply_async(func, (msg, ))

    print("M~ M~ M~~~~~~~~~~~~~~~~~~~~~~")
    pool.close()
    pool.join()
    print("Sub-process(es) done.")


输出:
M~ M~ M~~~~~~~~~~~~~~~~~~~~~~
msg: hello 0
msg: hello 1
msg: hello 2
end
end
end
Sub-process(es) done.

使用 multiprocessing.Pool 阻塞版本

import multiprocessing
import time

def func(msg):
    print("msg:", msg)
    time.sleep(3)
    print("end")

if __name__ == "__main__":
    pool = multiprocessing.Pool(processes = 3)
    for i in range(3):
        msg = "hello %d" %(i)
        pool.apply(func, (msg, ))

    print("M~ M~ M~~~~~~~~~~~~~~~~~~~~~~")
    pool.close()
    pool.join()
    print("Sub-process(es) done.")

输出:
msg: hello 0
end
msg: hello 1
end
msg: hello 2
end
M~ M~ M~~~~~~~~~~~~~~~~~~~~~~
Sub-process(es) done.

区别主要是 apply_async和apply函数,前者是非阻塞的,后者是阻塞

小结

在Unix/Linux下,可以使用fork()调用实现多进程。

要实现跨平台的多进程,可以使用multiprocessing模块。

相关阅读


相关推荐
  1. 宝贝归谁
  2. 车企数字化转型(下)
  3.  巫师换心记
  4. 央媒聚焦!国庆假期173.78万人次打卡大美黄陂
  5. 机器学习 - 监督学习概述
  6. 南京汉开书院
  7. 武汉一女子七天被骗220万
  8. 中山市坦洲镇同胜小学
  9. 民歌的鸟儿
  10. 武汉女子网上做兼职被骗六十五万
  11. 马上得天下
  12. 武汉动物园火烈鸟孔雀排队打疫苗
  13. 沈阳市法库县育豪智能双语幼儿园 - 沈阳幼儿园黄页
  14. 望娘滩
  15. 宝宝奶粉用自来水还是纯净水 - 育儿经验
  16. 北京市丰台区东高地第三小学(东高地三小)
  17. Python基础视频教程 - 七天学会Python
  18. 淄博市博山区考院小学
  19. 武汉市博物馆一日游
  20. 脱单!武汉的相亲角在哪你知道吗?
  21. 早产儿易发生哪些疾病 - 育儿经验
  22. 淄博市淄川区岭子镇中心小学
  23. 江苏省常州高级中学
  24. 一休双语幼儿园 - 石家庄幼儿园黄页
  25. 上海市浦东新区上南三村小学
  26. 启动TOGAF之前的10个步骤 - TOGAF系列教程(2)
  27. 青龙满族自治县第一中学(青龙一中)
  28. 事发武汉农夫山泉矿泉水内惊现大量虫卵
  29. 惠州市第三小学
  30. 柳州市柳城县小白鸽幼儿园 - 柳州市幼儿园黄页
  31. 乾隆横招贼要店
  32. 江门市新会区大泽镇沿江小学
  33. 北师大附中京西校区
  34. 滦平县第一中学(滦平一中)
  35. 约法三章
  36. 流泪的老鼠米米
  37. 沈阳市于洪区贝莱特幼稚园 - 沈阳幼儿园黄页
  38. Centos7中配置 Putty免密码登录
  39. Python公开课 - 爬虫介绍
  40. 武汉推出越王勾践剑交通卡
  41. 长沙市宁乡县城北中学
  42. Python公开课 - 数据抓取之Selenium使用(上)
  43. 杨营镇第二中学
  44. 易中天给英雄武汉的一首诗 - 武汉新鲜事
  45. 百名网媒总编辑登上知音号欣赏武汉夜色
  46. 成都市青羊区战旗幼稚园 - 成都市幼儿园黄页
  47. 青岛东胜路小学
  48. 宜春一中
  49. 微服务架构 Spring Cloud 理解与思考
  50. 淄博市张店区湖田中学
  51. 警方通报:武汉男子持刀至五死一伤,嫌犯已跳桥
  52. 育童幼儿园 - 石家庄幼儿园黄页
  53. 国王是个糊涂虫
  54. 沧州市黄骅市新星艺术幼儿园 - 沧州幼儿园黄页
  55. 遵义市正安县瑞溪镇中心幼儿园 - 遵义市幼儿园黄页
  56. 西安雁塔区东仪路小学
  57. 长沙市浏阳市大瑶镇料源完全小学
  58. 洛阳市河洛中学(初中)
  59. 鲑鱼王
  60. 什么是TCP中三次握手和四次挥手