Python 进程(process)
1. 进程
1.1 进程的创建 fork
- 正在运行着的代码,就称为进程
# 示例:
import os
# 注意: fork 函数,只在 Unix/Linux/Mac 上运行, windows 不可以
pid = os.fork()
print(pid)
if pid == 0:
# 子进程执行(pid==0)
print("=== 子进程 === %d %d" % (os.getpid(),os.getppid()))
else:
# 主(父)进程执行(pid>0)
print("=== 父进程 ===%d" % os.getpid())
1.2 全局变量在进程中不共享
# 示例:
import os
import time
g_num = 100
ret = os.fork()
if ret == 0:
print("=== process 1 ===")
g_num += 1
print("=== process 1 g_num = %d===" % g_num)
else:
time.sleep(3)
print("=== process 2 ===")
print("=== process 2 g_num = %d ===" % g_num)
# 输出:
=== process 1 ===
=== process 1 g_num = 101 ===
=== process 2 ===
=== process 2 g_num = 100 ===
1.3 多次fork
# 示例:
import os
ret = os.fork()
if ret == 0:
print("=== 1 ===")
else:
print("=== 2 ===")
ret = os.fork()
if ret == 0:
print("=== 3 ===")
else:
print("=== 4 ===")
# 输出:
=== 2 ===
=== 4 ===
=== 1 ===
=== 3 ===
=== 4 ===
=== 3 ===
1.4 Process 创建子进程
# 示例
from multiprocessing import Process
import os
# 子进程要执行的代码
def run_proc(name):
print('子进程运行中, name=%s, pid=%d...' % (name, os.getpid()))
if __name__=='__main__':
print('父进程 %d.' % os.getpid())
p = Process(target=run_proc, args=('test',))
print('子进程将要执行')
p.start() # 创建子进程
p.join() # 等到子进程实例(p)执行结束后,才执行后面的代码
print('子进程已结束')
1.5 Process 的子类
# 示例:
from multiprocessing import Process
import time
import os
# 继承Process类
class Process_Class(Process):
# 因为Process类本身也有 __init__ 方法,这个类相当于重写了这个方法;
# 但这样就会带来一个问题,我们并没有完全的初始化一个 Process 类, 所以就不能使用从这个类继承的一些方法
# 最好的方法就是将继承类本身传递给 Process.__init__ 方法, 完成这些初始化操作
def __init__(self, interval):
# super(Process_Class, self).__init__()
Process.__init__(self)
self.interval = interval
# 重写Process类的run()方法
def run(self):
print("子进程(%s) 开始执行, 父进程为 (%s)" % (os.getpid(), os.getppid()))
t_start = time.time()
time.sleep(self.interval)
t_stop = time.time()
print("(%s)执行结束, 耗时%0.2f秒" % (os.getpid(), t_stop-t_start))
if __name__=="__main__":
t_start = time.time()
print("当前进程(%s)" % os.getpid())
p1 = Process_Class(2)
# 对一个不包含target属性的Process类执行start()方法,就会运行这个类中的 run() 方法
p1.start()
p1.join()
t_stop = time.time()
print("(%s)执行结束, 耗时%0.2f" % (os.getpid(), t_stop-t_start))
1.6 进程池 Pool(非阻塞方式)
# 示例:
from multiprocessing import Pool
import os, time, random
def worker(msg):
t_start = time.time()
print("%s开始执行, 进程号为%d" % (msg, os.getpid()))
# random.random()随机生成0~1之间的浮点数
time.sleep(random.random()*2)
t_stop = time.time()
print(msg, "执行完毕, 耗时%0.2f" % (t_stop-t_start))
po = Pool(3) # 定义一个进程池, 最大进程数 3
for i in range(0, 10):
# Pool.apply_async(要调用的目标,(传递给目标的参数元组,))
# 每次循环将会用空闲出来的子进程去调用目标
po.apply_async(worker,(i,))
print("=== start ===")
po.close() # 关闭进程池,关闭后po不再接收新的请求
po.join() # 等待po中所有子进程执行完成, 必须放在close语句之后
print("=== close ===")
1.7 apply 阻塞方式添加任务
# 示例:
from multiprocessing import Pool
import os, time, random
def worker(msg):
t_start = time.time()
print("%s开始执行, 进程号为%d" % (msg, os.getpid()))
# random.random()随机生成0~1之间的浮点数
time.sleep(random.random()*2)
t_stop = time.time()
print(msg, "执行完毕, 耗时%0.2f" % (t_stop-t_start))
po = Pool(3) # 定义一个进程池, 最大进程数 3
for i in range(0, 10):
po.apply(worker, (i,))
print("=== start ===")
po.close()
po.join()
print("=== close ===")
1.8 进程间通信(Queue)
# 示例一: Queue 存取数据
from multiprocessing import Queue
q=Queue(3) # 初始化一个Queue对象,最多可接收三条put消息
q.put("消息1")
q.put("消息2")
print(q.full()) # False
q.put("消息3")
print(q.full()) # True
# 因为消息队列已满,下面的try会抛出异常,第一个try会等待2秒后再抛出异常,第二个try会立刻抛出异常
try:
q.put("消息4",True,2)
except:
print("消息队列已满,现有消息数量: %s" % q.qsize())
try:
q.put_nowait("消息4")
except:
print("消息队列已满,现有消息数量: %s" % q.qsize())
# 推荐的方式: 先判断消息队列是否已满, 再写入
if not q.full():
q.put_nowait("消息4")
# 读取消息时, 先判断消息队列是否为空,再读取
if not q.empty():
for i in range(q.qsize()):
print(q.get_nowait())
# 示例二: 进程间通信
# 在父进程中创建两个子进程,一个往Queue里写数据, 一个从Queue里读数据
from multiprocessing import Process, Queue
import os, time, random
# 写数据进程执行代码
def write(q):
for value in ['A', 'B', 'C']:
print('Put %s to queue...' % value)
q.put(value)
time.sleep(random.random())
# 读数据进程执行代码
def read(q):
while True:
if not q.empty():
value = q.get(True)
print('Get %s from queue.' % value)
time.sleep(random.random())
else:
break
if __name__=='__main__':
# 父进程创建Queue,并传给各子进程
q = Queue()
pw = Process(target=write, args=(q,))
pr = Process(target=read, args=(q,))
# 启动子进程pw, 写入:
pw.start()
# 等待pw结束
pw.join()
# 启动子进程pr, 读取:
pr.start()
pr.join()
# 所有子进程执行结束,输出
print('所有数据都写入并读完')
1.8.1 进程间通信(Pipe)
# 示例:
from multiprocessing import Process, Pipe
def f(conn):
conn.send([33, None, 'hello'])
conn.close()
if __name__ = '__main__':
parent_conn, child_conn = Pipe()
p = Process(target = f, args = (child_conn, ))
p.start()
print(parent_conn.recv())
p.join()
1.9 进程池中的Queue
- 在进程池中,需要使用
multiprocessing.Manager()中的Queue();而不是multiprocessing.Queue()
# 示例:
from multiprocessing import Manager, Pool
import os, time, random
# 写数据进程执行代码
def reader(q):
print("reader启动(%s), 父进程为(%s)" % (os.getpid(), os.getppid()))
for i in range(q.qsize()):
print("reader从Queue获取到消息: %s" %q.get(True))
# 读数据进程执行代码:
def writer(q):
print("writer启动(%s), 父进程为(%s)" % (os.getpid(), os.getppid()))
for i in ['A', 'B', 'C']:
q.put(i)
if __name__=="__main__":
print("(%s) start" % os.getpid())
q=Manager().Queue() # 使用Manager中的Queue来初始化
po=Pool()
# 使用阻塞模式创建进程,这样就不需要在reader中使用死循环了, 可以让writer执行完成后,再用reader读取
po.apply(writer,(q,))
po.apply(reader,(q,))
po.close()
po.join()
print("(%s) End" % os.getpid())
参考资料:
Python 进程(process)的更多相关文章
- 60%的人不懂Python进程Process,你懂吗?
前言本文的文字及图片来源于网络,仅供学习.交流使用,不具有任何商业用途,版权归原作者所有,如有问题请及时联系我们以作处理.作者:蒋狗 新手注意:如果你Python基础学的不够扎实,遇问题没人解答 ...
- python——进程基础
我们现在都知道python的多线程是个坑了,那么多进程在这个时候就变得很必要了.多进程实现了多CPU的利用,效率简直棒棒哒~~~ 拥有一个多进程程序: #!/usr/bin/env python #- ...
- python进程、线程、协程(转载)
python 线程与进程简介 进程与线程的历史 我们都知道计算机是由硬件和软件组成的.硬件中的CPU是计算机的核心,它承担计算机的所有任务. 操作系统是运行在硬件之上的软件,是计算机的管理者,它负责资 ...
- Python进程、线程、协程详解
进程与线程的历史 我们都知道计算机是由硬件和软件组成的.硬件中的CPU是计算机的核心,它承担计算机的所有任务. 操作系统是运行在硬件之上的软件,是计算机的管理者,它负责资源的管理和分配.任务的调度. ...
- python进程池剖析(一)
python中两个常用来处理进程的模块分别是subprocess和multiprocessing,其中subprocess通常用于执行外部程序,比如一些第三方应用程序,而不是Python程序.如果需要 ...
- python——进程、线程、协程
Python线程 Threading用于提供线程相关的操作,线程是应用程序中工作的最小单元. 1 2 3 4 5 6 7 8 9 10 11 12 13 14 #!/usr/bin/env pytho ...
- python 进程介绍 进程简单使用 join 验证空间隔离
一.多道程序设计技术(详情参考:https://www.cnblogs.com/clschao/articles/9613464.html) 所谓多道程序设计技术,就是指允许多个程序同时进入内存并运行 ...
- Python 进程之间共享数据
最近遇到多进程共享数据的问题,到网上查了有几篇博客写的蛮好的,记录下来方便以后查看. 一.Python multiprocessing 跨进程对象共享 在mp库当中,跨进程对象共享有三种方式,第一种 ...
- python进程、多进程
进程: 进程(Process)是计算机中的程序关于某数据集合上的一次运行活动,是系统进行资源分配和调度的基本单位,是操作系统结构的基础.在早期面向进程设计的计算机结构中,进程是程序的基本执行实体:在当 ...
随机推荐
- FileInputStream与FileOutputStream类
FileInputStream和FileOutputStream类分别用来创建磁盘文件的输入流和输出流对象,通过它们的构造函数来指定文件路径和文件名. 创建FileInputStream实例对象时,指 ...
- Android中<uses-sdk>属性和target属性分析
1. 概要 <uses-sdk> 用来描述该应用程序可以运行的最小和最大API级别,以及应用程序开发者设计期望运行的平台版本.通过在manifest清单文件中添加该属性,我们可以更好的控制 ...
- CodeForces 558D
Guess Your Way Out! II Time Limit:2000MS Memory Limit:262144KB 64bit IO Format:%I64d & ...
- 纯css3实现的鼠标悬停动画按钮
今天给大家带来一款纯css3实现的鼠标悬停动画按钮.这款按钮鼠标经过前以正方形的形式,当鼠标经过的时候以动画的形式变成圆形.效果图如下: 在线预览 源码下载 实现的代码. html代码: < ...
- 生产者和消费者问题学习以及Java实现
在计算机领域中,生产者-消费者问题(也叫bounded-buffer问题)是一类很经典的多进程同步问题.该问题描述了两类进程,即生产者进程和消费者进程,它们共享一个固定大小的缓冲区作为队列.生产者的任 ...
- C/C++基础问题归集
include " ":先从本地目录,后从系统路径include <>: 先从系统路径,后从本地目录 一般用哪个都没关系,只是速度有差别罢了
- div随页面滚动遇顶固定的两种方法(js&jQuery)
一.遇顶固定的例子 我一直以为是某个div或层随屏幕滚动,遇顶则固定,离开浏览器顶部又还原这样的例子其实不少,其实它的名字叫“层的智能浮动效果”.目前我们在国内的商业网站上就常常看到这样的效果了.例如 ...
- 【转】伪O2O已死?2016年实体零售将迎来真正的O2O
O2O果真如所谓的经济学家许小年所说“是两边都是零,中间一个2货”吗?我觉得,经济学家不是说相声的,这种哗众取宠的观点不应该出自一个严谨的经济学家之口.而且,我也不认为许小年真正懂什么叫O2O. 但O ...
- pydoc介绍
Ka-Ping Yee 曾创建了一个相当著名的模块,名叫 pydoc (比较而言: pydoc 可以做到 perldoc 所能做的任何事,并且做得更好.更漂亮:-).对于 Python 2.1 来说, ...
- querySelectorAll 和getElementsByClassName的区别
querySelectorAll 返回的是映射 改变其值不会改变document 而getElementsByClassName 改变它就会改变document 摘自JavaScript权威指南(jQ ...