python 学习笔记 多进程
要让python程序实现多进程,我们先了解操作系统的相关知识
Unix/Linux操作系统提供了一个fork()系统调用,他非常特殊,普通的函数调用,调用一次,返回一次,但是fork调用一次,
返回两次,因为操作系统自动把当前进程称为父进程复制了一份,然后,分别在父进程和子进程返回。
子进程永远返回0,而父进程返回子进程的ID.这样做的理由是,一个父进程可以fork出很多子进程,所以父进程要记下来
子进程的ID,而子进程只需要调用getppid()就可以拿到父进程的id
Python的OS模块封装了常见的系统调用,其中就包括fork,可以在python程序中轻松创建子进程
import os
print('Process (%s) start...' % os.getpid())
# Only works on Unix/Linux/Mac:
pid = os.fork()
if pid == 0:
print('I am child process (%s) and my parent is %s.' % (os.getpid(), os.getppid()))
else:
print('I (%s) just created a child process (%s).' % (os.getpid(), pid))
有了fork调用,一个进程在接到新任务时就可以复制出一个子进程来处理新任务,常见的Apache服务器就是由父进程监听端口,每当有新的http请求时,就fork出子进程来处理新的http请求。
由于Windows没有fork调用,上面的代码在Windows上无法运行。由于Mac系统是基于BSD(Unix的一种)内核,所以,在Mac下运行是没有问题的,推荐大家用Mac学Python!
有了fork调用,一个进程在接到新任务时就可以复制出一个子进程来处理新任务,常见的Apache服务器就是由父进程监听端口,每当有新的http请求时,就fork出子进程来处理新的http请求。
multiprocessing
如果你打算编写多进程的服务程序,Unix/Linux无疑是正确的选择。由于Windows没有fork调用,难道在Windows上无法用Python编写多进程的程序?
由于Python是跨平台的,自然也应该提供一个跨平台的多进程支持。multiprocessing模块就是跨平台版本的多进程模块。
multiprocessing模块提供了一个Process类来代表一个进程对象,下面的例子演示了启动一个子进程并等待其结束:
from multiprocessing import Process
import os # 子进程要执行的代码
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.')
创建子进程时,只需要传入一个执行函数和函数的参数,创建一个Process实例,用start()方法启动,这样创建进程比fork()还要简单。 join()方法可以等待子进程结束后再继续往下运行,通常用于进程间的同步。
Pool
如果要启动大量的子进程,可以用进程池的方式批量创建子进程:
from multiprocessing import Pool
import os, time, random 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 runs %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 subprocesses done...')
p.close()
p.join()
print('All subprocesses done.')
执行结果类似下面
Parent process 669.
Waiting for all subprocesses done...
Run task 0 (671)...
Run task 1 (672)...
Run task 2 (673)...
Run task 3 (674)...
Task 2 runs 0.14 seconds.
Run task 4 (673)...
Task 1 runs 0.27 seconds.
Task 3 runs 0.86 seconds.
Task 0 runs 1.41 seconds.
Task 4 runs 1.91 seconds.
All subprocesses done.
子进程
很多时候,子进程并不是自身,而是一个外部进程。我们创建了子进程后,还需要控制子进程的输入和输出。
subprocess模块可以让我们非常方便地启动一个子进程,然后控制其输入和输出。
下面的例子演示了如何在Python代码中运行命令nslookup www.python.org,这和命令行直接运行的效果是一样的:
进程间通信
Process之间肯定是需要通信的,操作系统提供了很多机制来实现进程间的通信。Python的multiprocessing模块包装了底层的机制,提供了Queue、Pipes等多种方式来交换数据。
我们以Queue为例,在父进程中创建两个子进程,一个往Queue里写数据,一个从Queue里读数据:
from multiprocessing import Process, Queue
import os, time, random # 写数据进程执行的代码:
def write(q):
print('Process to write: %s' % os.getpid())
for value in ['A', 'B', 'C']:
print('Put %s to 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()
在Unix/Linux下,multiprocessing模块封装了fork()调用,使我们不需要关注fork()的细节。由于Windows没有fork调用,因此,multiprocessing需要“模拟”出fork的效果,父进程所有Python对象都必须通过pickle序列化再传到子进程去,所有,如果multiprocessing在Windows下调用失败了,要先考虑是不是pickle失败了。
python 学习笔记 多进程的更多相关文章
- Python 学习笔记 多进程 multiprocessing--转载
本文链接地址 http://quqiuzhu.com/2016/python-multiprocessing/ Python 解释器有一个全局解释器锁(PIL),导致每个 Python 进程中最多同时 ...
- python学习笔记-多进程
multiprocessing from multiprocessing import Process import time def f(name): time.sleep(2) print('he ...
- python学习笔记——多进程中的锁Lock
1 进程锁 python编程中,引入了对象互斥锁的概念,来保证共享数据操作的完整性. 每个对象都对应于一个可称为“互斥锁”的标记,这个标记用来保证在任一时刻,只能有一线程访问对象. 在python中我 ...
- python学习笔记——多进程中共享内存Value & Array
1 共享内存 基本特点: (1)共享内存是一种最为高效的进程间通信方式,进程可以直接读写内存,而不需要任何数据的拷贝. (2)为了在多个进程间交换信息,内核专门留出了一块内存区,可以由需要访问的进程将 ...
- python学习笔记—— 多进程中的 孤儿进程和僵尸进程
1 基本概述 1.1 孤儿进程和僵尸进程 父进程创建子进程后,较为理想状态是子进程结束,父进程回收子进程并释放子进程占有的资源:而实际上,父子进程是异步过程,两者谁先结束是无顺的,一般可以通过父进程调 ...
- python学习笔记——多进程二 进程的退出
1 进程的退出函数的基础语法 1.1 进程的退出函数 进程的退出含有有os._exit([status])和sys.exit([status])两种,从数据包来看,该退出模块仅在linux或者unix ...
- python学习笔记——多进程一 基础概念
1 进程 进程:程序的一次(从开始到结束)执行过程,属于一个动态过程.是系统进行资源分配和调度的基本单位. 程序:指的是一个文件,磁盘中可执行的代码.属于一个静态文件 注:进程运行时需要把程序加载如内 ...
- Python学习笔记进阶篇——总览
Python学习笔记——进阶篇[第八周]———进程.线程.协程篇(Socket编程进阶&多线程.多进程) Python学习笔记——进阶篇[第八周]———进程.线程.协程篇(异常处理) Pyth ...
- python学习笔记整理——字典
python学习笔记整理 数据结构--字典 无序的 {键:值} 对集合 用于查询的方法 len(d) Return the number of items in the dictionary d. 返 ...
随机推荐
- mysql 5.7.18 源码安装笔记
之所以贴出这样一篇笔记呢?主要是因为很久之前,源码安装MySQL的时候,碰到了太多太多的坎坷. 如果你有兴趣进行源码安装,那么请不要以这篇文章为标准,因为每个人的及其环境等其他因素还是差距比较大的. ...
- (原)自定义资源预览工具:DZAssetPreviewPlugin(1)
@author: 白袍小道 转载请说明,谢谢 题记 后续工具制作单独作为一本(小道用的是OneNote,这样发布简单点.*--*) 总计放到写完后. 目的 1.快速预览资源(因为大部分 ...
- Oracle to MySQL Goldengate实现增量迁移
第一部分:安装和基本配置 一.环境 两台rhel 6.4虚拟机,分别异构oracle到mysql数据库同步测试Ip:192.168.0.23 部署oracle 11.2.0.4,goldgate 12 ...
- 剑指offer-用两个栈实现队列05
class Solution: def __init__(self): self.stackpush=[] self.stackpop=[] def push(self, node): # write ...
- mysql 数据库 exists 和count
由于最近在使用exists是出现了一个小问题,但是在调试的时候费了不少时间,因为自己只是牢固造成,所以在在此记录,已提醒自己. mysql中exists 用法: 通过和主查询管理 以达到过滤的效果,如 ...
- KMP板子+Trie板子
KMP算法是一个字符串匹配算法,最直白的用法就是在一个长度为n的字符串T中查找另一个长度为m字符串P的匹配(总之就是用于文本中进行单个字符串的匹配). 对于这个问题,暴力算法是很好做的,直接对于T的每 ...
- [Mac]Mac OS X中WireShark的使用,及找不到网卡问题的解决方法
1.WireShark依赖X11: 2.默认情况下Mac OS X是不安装X11的: 因此,在Mac上安装WireShark,首先找出Mac OS 安装DVD安装X11. 安装完以后 echo $DI ...
- Python中运算符"=="和"is"的差别分析
前言 在讲is和==这两种运算符区别之前,首先要知道Python中对象包含的三个基本要素,分别是:id(身份标识).python type()(数据类型)和value(值).is和==都是对对象进行比 ...
- Android—基于OpenCV+Android实现人脸检测
导读 OpenCV 是一个开源的跨平台计算机视觉库, 采C++语言编写,实现了图像处理和计算机视觉方面的很多通用算法,同时也提供对Python,Java,Android等的支持,这里利用Android ...
- 关于aspnet_regsql使用方法
aspnet_regsql命令解释 说明该向导主要用于配置SQL Server数据库,如membership,profiles等信息,如果要配置SqlCacheDependency,则需要以命令行的方 ...