python之多进程
要让python实现多进程「multiprocessing」。我们先来了解操作系统相关知识。
Unix 和 Linux 操作系统提供了一个 fork() 函数系统调用,它非常特殊。普通的函数,调用一它次,执行一次,但是 fork() 函数调用一次执行两次,因为操作系统自动把当前进程「称为父进程」复制了一份「称为子进程」,然后,分别在子进程和父进程中执行。
子进程永远返回0,而父进程返回子进程的 ID。这样做的理由是,一个父进程可以 fork() 多个子进程,所以父进程要记下所有子进程的 ID,而子进程只要调用 getppid() 就可以拿到父进程的 ID。
python中 os 模块封装了常见的系统调用,其中就包括 fork(),可以在python程序中轻松创建子程序:
import os print('Process (%s) start ...' % os.getpid()) #Only work on Unix/linux/Mac #不能在Windows平台上运行 pid = os.fork() if pid == 0: print('I am child process (%) and my parent is %s.' % (os.getpid(),os.getppid())) else: print('I (%) just created a child process (%).' % (os.getpid(),pid))
运行结果:
Process (876) start... I (876) just created a child process (877). I am child process (877) and my parent is 876.
由于 Windows 平台下没有 fork() 函数调用,所以代码没有办法在 Windows平台下运行。
有了 fork 调用,一个进程在接到任务的时候就可以复杂出来一个子进程来处理新任务,常见的 Apache 服务器就是由父进程监听端口,每当有新的 http 请求时,就 fork 出新的子进程来处理新的 http 请求。
multiprocessing「多进程」
如果你想写多进程的服务程序,Unix/Linux 平台最好了,当然也可以在 Windows 平台下来编写,因为 python 跨平台。multiprocessing 模块就是跨平台版本的多进程模块。
multiprocessing 模块提供了一个 Process 类来代表一个进程对象,下面一个例子用来演示启动一个子进程并等待结束的例子:
import os from multiprocessing import Process #子进程要执行的代码 def run_proc(name): print('Run child process %s (%s)' % (name,os.getpid())) if __name__ == '__main__': print('parent process %s' % os.getpid()) p = Process(target=run_proc,args=('test',))#创建子程序 print('Child process will start') p.start()#子程序开始执行 p.join() print('Child process end.')
- 创建子程序时,只需要传入一个执行的函数和函数的参数。
- 创建一个 Procsess 实例,用 start() 方式开启,这样创建的进程比 fork 还简单。
- join() 方法可以等jinc子进程执行完后再继续往下运行,通常用于进程之间的同步。
Pool
如果想要启动大量的子进程,可以用进程池的方式批量创建子进程。
import os,time,random from multiprocessing import Pool def long_time_task(name): print('Run task %s (%s)...' % (name,os.getpid())) start = time.time() time.sleep(random.random() * 3) end = time.time() print('Task %s run %0.2f seconds.' % (name,(end-start))) if __name__ == '__main__': print('Parent process %s.' % os.getpid()) p = Pool(4) for i in range(5): p.apply_async(long_time_task,args=(i,)) print('Waiting for all subprocess done...') p.close() p.join() print('All subprocess done')
执行结果:
Parent process 7600. Waiting for all subprocess done... Run task 0 (11392)... Run task 1 (6432)... Run task 2 (10768)... Run task 3 (5116)... Task 0 run 0.03 seconds. Run task 4 (11392)... Task 3 run 1.42 seconds. Task 1 run 1.77 seconds. Task 4 run 2.59 seconds. Task 2 run 2.93 seconds. All subprocess done Process finished with exit code 0
- 对Pool调用 join() 方法会等所用子进程执行完毕,调用 join() 之前一定要调用 close() 调用 close() 之后不能在有新的process
- 程序的输出结果显示 task 0、1、2、3 是同时执行的,而 task 4 是等前四个执行完毕才执行,这是因为,进程池在我的电脑上是4。,因此最多执行四个进程,这是 Pool 有意设计的限制,并不是操作系统的限制,如果你改成
p = Pool(5)
就可以同时跑 5 个进程。
子进程
很多时候,子进程并不是本身,热是一个外部的进程。我们创建了子进程之后,还要控制进程的输入和输出。
subprocess 模块可以让我们非常方便的启动一个子进程,然后控制输入和输出。
这一部分未完待续
进程间的通信
Process 间肯定是要通信的,操作系统提供了很多机制来实现进程间的通信,python 中的 multiprocessing 模块包装了底层的机制,提供了 Queue、Pipes 等多种方法来交换数据。
我们以 Queue 为例,在父进程中创建两个子进程,一个往 Queue 里写数据,一个从 Queue 中读数据。
from multiprocessing import Queue,Process import os,time,random #写数据进程执行的代码 def write(q): print('Process to write : %s' % os.getpid()) for value in ['A','B','C']: print('Put %s queue...' % value) q.put(value) time.sleep(random.random()) #读数据执行的代码 def read(q): print('Process to read : %s' % os.getpid()) while True: value = q.get(True) print('Get %s from queue.' % value) if __name__ == '__main__': #父进程创建Queue,并传给各个子进程 q = Queue() pw = Process(target=write,args=(q,)) pr = Process(target=read,args=(q,)) #启动子程序pw,写入: pw.start() #启动子程序pr,读取: pr.start() #等待pw结束: pw.join() #pr进程是死循环,无法等待它结束,只能强行终止。 pr.terminate()
运行结果
Process to read : 8416 Process to write : 12840 Put A queue... Get A from queue. Put B queue... Get B from queue. Put C queue... Get C from queue. Process finished with exit code 0
- 在Windows 平台下实现多进程,用multiprocessing 模块
- 进程间的通信是用 Queue 、Pipes 来进行的。
低调大师中文资讯倾力打造互联网数据资讯、行业资源、电子商务、移动互联网、网络营销平台。
持续更新报道IT业界、互联网、市场资讯、驱动更新,是最及时权威的产业资讯及硬件资讯报道平台。
转载内容版权归作者及来源网站所有,本站原创内容转载请注明来源。
- 上一篇
看看80万程序员怎么评论:程序员工资为什么这么高?
先说几句话:为什么程序员被黑的时候,大家都很开心;一看到程序员工资高了,你tm眼红了,我x!你是有多瞧不起我们这个行业啊!当今世界苹果,谷歌,阿里巴巴,facebook 等等 都是我程序员靠双手写出来的天下!你现在用的知乎也是!程序员让这个世界变得这么精彩,md工资高了还要被你吐槽!说句实话,程序员这个工作,有两个地方吸引人!一是工资,不多说,大家都喜欢钱! 第二,最重要的一点是热情!只有一个对程序对代码充满热情的人,才能把这份工作做好!剩下的都是被各种人骂,各种人黑,各种人嘲笑!来看看大佬们都是怎么看待这个问题的吧! 最后再来给程序员点建议: 对于这个问题,IT从业者和非IT从业者分歧很大,有很大一部分原因是IT从业者和非从业者完全处在两个世界,很多人学了如日中天的计算机专业,毕业顺利找到工作。那些为专业所累,苦苦找不到工作的滋味,又岂是这些人能体会得到的。做着高强度的工作,每月拿着入不敷出的工资的人不要太多! 欢迎工作一到五年的Java工程师朋友们加入Java架构开发:744677563 本群提供免费的学习指导 架构资料 以及免费的解答 不懂得问题都可以在本群提出来 之后还会有职...
- 下一篇
计算机c语言好学吗?要是想自学应该怎么办?
C语言放在之前都是必备的基础语言,由于指针的存在很多人觉得C语言是一门特别难编程语言,放在十年前C语言是学习编程的必备语言,但整个软件行业发展趋势,趋向于高度集成化,所以编程语言集成度越来越高,目前非常流行的编程语言都高度集成化的编程语言 1.python 2.java 3.前端 这三种语言是目前初学者选择比较多的语言,在以前这些都属于脚本语言,所谓脚本语言的底层功能模块都是封装起来的,直接调用拿到结果,现在慢慢向着主流编程语言迈进的趋势了,特别最近特别火的python 是不是C语言不值得学习了? 这种顾虑完全没有必要,python底层实现基本上由C语言完成,所以不要再听什么C语言已经过时之类的论调了。 那么C语言想要自学需要具备两个条件: 1.对编程特别的感兴趣,兴趣才是第一老师,有了兴趣中间遇到问题才能克服 2.觉得编程工资还不低,能够满足自己当前急缺钱的现状,基于这点强大的内心驱动力也能够让自己遇到困难的时候克服过去。 如果不满足前面的条件不建议匆忙就开始学习C语言 如何自学? 1. 首先选择一门入门的书籍,c primer plus 适合初学者入门 2. 制定详细的学习计划,遇...
相关文章
文章评论
共有0条评论来说两句吧...
文章二维码
点击排行
推荐阅读
最新文章
- Springboot2将连接池hikari替换为druid,体验最强大的数据库连接池
- SpringBoot2更换Tomcat为Jetty,小型站点的福音
- Docker安装Oracle12C,快速搭建Oracle学习环境
- CentOS7编译安装Gcc9.2.0,解决mysql等软件编译问题
- CentOS6,CentOS7官方镜像安装Oracle11G
- CentOS关闭SELinux安全模块
- CentOS7设置SWAP分区,小内存服务器的救世主
- CentOS7,CentOS8安装Elasticsearch6.8.6
- CentOS7编译安装Cmake3.16.3,解决mysql等软件编译问题
- Jdk安装(Linux,MacOS,Windows),包含三大操作系统的最全安装