Python之多线程与多进程(二)
多进程
上一章:Python多线程与多进程(一)
由于GIL的存在,Python的多线程并没有实现真正的并行。因此,一些问题使用threading模块并不能解决
不过Python为并行提供了一个替代方法:多进程。在多进程里,线程被换成一个个子进程。每个进程都运作着各自的GIL(这样Python就可以并行开启多个进程,没有数量限制)。需要明确的是,线程都是同一个进程的组成部分,它们共享同一块内存、存储空间和计算资源。而进程却不会与它们的父进程共享内存,因此进程间通信比线程间通信更为复杂
多进程相比多线程优缺点如下:
优点 | 缺点 |
可以使用多核操作系统 | 更多的内存消耗 |
进程使用独立的内存空间,避免竞态问题 | 进程间的数据共享变得更加困难 |
子进程容易中断 | 进程间通信比线程困难 |
避开GIL限制 |
Python多进程
multiprocessing模块提供了一个Process类,它有点类似多线程模块中threading.Thread类。因此,把多线程代码迁移到多进程还是比较简单的,因为代码的基本结构不变
我们快速演示一个多进程的示例:
import multiprocessing def run(pname):
print(pname) for i in range(3):
p = multiprocessing.Process(target=run, args=("Process-%s" % i,))
p.start()
p.join()
运行结果:
Process-0
Process-1
Process-2
可以看出,多进程和多线程的代码非常像,这里需要注意一点,如果是在Windows上执行的需要把启动进程的代码放到if __name__ == "__main__":底下
if __name__ == "__main__":
for i in range(3):
p = multiprocessing.Process(target=run, args=("Process-%s" % i,))
p.start()
p.join()
进程退出状态:当进程结束的时候,会产生一个状态码,它是一个数字,表示执行结果,不同数字代表程序运行的不同情况:
- 等于0表示正常完结
- 大于0表示异常完结
- 小于0表示进程被另一个进程通过-1*exit_code信号终结
下面的代码演示如何读取和使用退出码
import multiprocessing
import time def first():
print("There is no problem here") def second():
raise RuntimeError("Error raised!") def third():
time.sleep(3)
print("This process will be terminated") workers = [multiprocessing.Process(target=first), multiprocessing.Process(target=second),
multiprocessing.Process(target=third)]
for w in workers:
w.start() workers[-1].terminate() for w in workers:
w.join() for w in workers:
print(w.exitcode)
运行结果:
There is no problem here
Process Process-2:
Traceback (most recent call last):
File "/home/lf/anconda3/lib/python3.6/multiprocessing/process.py", line 258, in _bootstrap
self.run()
File "/home/lf/anconda3/lib/python3.6/multiprocessing/process.py", line 93, in run
self._target(*self._args, **self._kwargs)
File "test01.py", line 11, in second
raise RuntimeError("Error raised!")
RuntimeError: Error raised!
0
1
-15
我们注意到,第三个子进程的print语句没有执行,这是因为在sleep方法结束之前进程已经被中止了。还有一点需要注意的是:两个独立的for循环处理三个子进程:一个启动子进程,另一个通过join方法连接进程。如果我们在开启每个子进程时都执行join方法,而不是没有join直接中断第三个进程,那么第三个进程就不会失败。于是第三个子进程返回的退出码也是0,因为和多线程一样,join方法在目标进程完结之前会阻塞子进程的调用
进程池
多进程模块还提供了pool类,表示一个进程池,里面装有子进程,可以通过不同的方法执行同一组任务。
Pool类的主要方法如下:
- apply:这个方法在独立的子进程中运行一个函数。它还会在被调用函数返回结果之前阻塞进程
- apply_async:这个方法会在独立子进程中异步地运行一个函数,就是说进程会立即返回一个ApplyResult对象,要获得真实的返回值需要使用get()方法。get()在异步执行的函数结束之前都会被阻塞
- map:这个方法对一组数值应用一个函数。它是一个阻塞动作,所以返回值是每个值经过函数映射的列表
进程间通信:进程间通信的方式不像线程间通信那么简单,但是,Python提供了一些工具帮助我们解决问题。
Queue类是一个既线程安全又进程安全的先进先出(FIFO)数据交换机制。multiprocessing提供的Queue类基本是Queue.Queue的克隆版本,因此二者API基本相同
from multiprocessing import Queue, Process
import random def generate(q):
while True:
value = random.randrange(10)
q.put(value)
print("Value added to queue: %s" % (value)) def reader(q):
while True:
value = q.get()
print("Value from queue: %s" % (value)) queue = Queue()
p1 = Process(target=generate, args=(queue,))
p2 = Process(target=reader, args=(queue,))
p1.start()
p2.start()
Pipe方法:Pipe(管道)方法为两个进程提供了一种双向通信的机制,Piped()函数返回一对连接对象,每个对象表示管道的一端。每个连接对象都有send()和recv()方法
from multiprocessing import Pipe, Process
import random def generate(pipe):
while True:
value = random.randrange(10)
pipe.send(value)
print("Value sent: %s" % (value)) def reader(pipe):
f = open("output.txt", "w")
while True:
value = pipe.recv()
f.write(str(value))
print(".") input_p, output_p = Pipe()
p1 = Process(target=generate, args=(input_p,))
p2 = Process(target=reader, args=(output_p,))
p1.start()
p2.start()
多进程也有事件Event,它们的工作方式与多线程类似,只是有一点需要记住,事件对象不能被传递到子进程的函数中,这样做会导致运行时错误,信号机制只能在主进程中被子进程共享:
from multiprocessing import Pool, Event
import time event = Event()
event.set() def worker(i):
if event.is_set():
time.sleep(0.1)
print("A - %s" % (time.time()))
event.clear()
else:
time.sleep(0.1)
print("B - %s" % (time.time()))
event.set() pool = Pool(3)
pool.map(worker, range(9))
Python之多线程与多进程(二)的更多相关文章
- Python之多线程和多进程
一.多线程 1.顺序执行单个线程,注意要顺序执行的话,需要用join. #coding=utf-8 from threading import Thread import time def my_co ...
- python的多线程和多进程(一)
在进入主题之前,我们先学习一下并发和并行的概念: --并发:在操作系统中,并发是指一个时间段中有几个程序都处于启动到运行完毕之间,且这几个程序都是在同一个处理机上运行.但任一时刻点上只有一个程序在处理 ...
- Python的多线程和多进程
(1)多线程的产生并不是因为发明了多核CPU甚至现在有多个CPU+多核的硬件,也不是因为多线程CPU运行效率比单线程高.单从CPU的运行效率上考虑,单任务进程及单线程效率是最高的,因为CPU没有任何进 ...
- Python【多线程与多进程】
import time,threading print("=======串行方式.并行两种方式调用run()函数=======")def run(): print('哈哈哈') # ...
- python的多线程、多进程代码示例
python多进程和多线程的区别:python的多线程不是真正意义上的多线程,由于python编译器的问题,导致python的多线程存在一个PIL锁,使得python的多线程的CPU利用率比预期的要低 ...
- selenium +python之多线程与多进程应用于自动化测试
多线程与多进程与自动化测试用例结合起来执行,从而节省测试用例的总体运行时间. 多线程执行测试测试用例 以百度搜索为例,通过不同的浏览器来启动不同的线程. from selenium import we ...
- Python之多线程与多进程(一)
多线程 多线程是程序在同样的上下文中同时运行多条线程的能力.这些线程共享同一个进程的资源,可以在并发模式(单核处理器)或并行模式(多核处理器)下执行多个任务 多线程有以下几个优点: 持续响应:在单线程 ...
- Python中多线程与多进程的恩恩怨怨
概念: 并发:当有多个线程在操作时,如果系统只有一个CPU,则它根本不可能真正同时进行一个以上的线程,它只能把CPU运行时间划分成若干个时间段,再将时间 段分配给各个线程执行,在一个时间段的线程代码运 ...
- python的多线程、多进程、协程用代码详解
前言 文的文字及图片来源于网络,仅供学习.交流使用,不具有任何商业用途,版权归原作者所有,如有问题请及时联系我们以作处理. 作者:刘早起早起 PS:如有需要Python学习资料的小伙伴可以加点击下方链 ...
随机推荐
- java中接口(interface)和虚基类(abstract class)的区别
在Java语言中,abstract class和interface是支持抽象类定义的两种机制.正是由于这两种机制的存在,才赋予了Java强大的面向对象能力.abstract class和interfa ...
- CSS grid layout demo 网格布局实例
直接 上代码,里面我加注释,相当的简单, 也可以去我的github上直接下载代码,顺手给个星:https://github.com/yurizhang/micro-finance-admin-syst ...
- Jquery each跳出循环
Jquery each跳出循环break--return false--跳出所有循环continue--return true--跳出当前循环
- iOS NSDecimalNumber 使用
在iOS开发中,经常遇到和货币价格计算相关的,这时就需要注意计算精度的问题.使用float类型运算,经常出现误差.为了解决这种问题我们使用NSDecimalNumber,下面将通过例子的形式给大家展示 ...
- uvm_mem——寄存器模型(十二)
看完了寄存器,再来看看存储器: //------------------------------------------------------------------------------ // ...
- 【装载】删除Oracle11G
卸载Oracle步骤:1.停止所有与ORACLE相关的服务.2. 使用OUI(Oracle Universal Installer)卸载Oracle软件. “开始”->“程序”->“O ...
- UVA 11214 Guarding the Chessboard 守卫棋盘(迭代加深+剪枝)
暴力,和八皇后很像,用表示i+j和i-j标记主对角线,但是还是要加一些的剪枝的. 1.最裸的暴搜 6.420s,差点超时 2.之前位置放过的就没必要在放了,每次从上一次放的位置开始放 0.400s # ...
- 使用Timer组件制作左右飘动的窗体
实现效果: 知识运用: Form类的Left和Top属性 实现代码: private void timer1_Tick(object sender, EventArgs e) { Rectangle ...
- 生成gt数据出问题
使用cout打印uchar类型数据时,打印出来是其相应的ascii码
- 【转】Java8学习笔记(1) -- 从函数式接口说起
http://blog.csdn.net/zxhoo/article/details/38349011 函数式接口 理解Functional Interface(函数式接口,以下简称FI)是学习Jav ...