MultiProcess-MultiThread
听到一些关于python多进程与多线的例子,感觉比较经典,把一些例子分享一下.
内容如下:
Process、Thread、GIL、Process fork、Multiprocessing、Queue、ProcessPool、Multiprocess-Multithread comparison
(1) Process : 程序的一次执行(程序编写完毕后代码装载入内存,系统分配资源运行)。每个进程有自己的内存空间、数据栈等,只能使用进 程间通讯,而不能直接共享信息
(2) Thread线程:所有线程运行在同一个进程中,共享相同的运行环境。 每个独立的线程有一个程序运行的入口、顺序执行序列和程序的出口; 线程的运行可以被抢占(中断),或暂时被挂起 (睡眠),让其他线程运行(让步);一个进程中的各个线程间共享同一片数据空间
(3) 全局解释器锁GIL
GIL全称全局解释器锁Global Interpreter Lock,GIL并不是Python的特性,它是在实现Python解析器(CPython)时 所引入的一个概念。
GIL是一把全局排他锁,同一时刻只有一个线程在运行。 毫无疑问全局锁的存在会对多线程的效率有不小影响。甚至就几乎等于Python是个单线程的程序。
multiprocessing库的出现很大程度上是为了弥补thread库因为 GIL而低效的缺陷。它完整的复制了一套thread所提供的接口方便迁移。唯一的不同就是它使用了多进程而不是多线程。每个进程有自己的独立的GIL,因此也不会出现进程之间的GIL争抢。
多线程处理的例子:
from threading import Thread
import time
def my_counter():i = 0for _ in range(100000000):i =i+1return True
def main():thread_array = {}start_time = time.time()for tid in range(2):t = Thread(target=my_counter())t.start()t.join()#以单线程、阻塞的方式顺序运行两次my_counter函数end_time = time.time()print("Total time:{}").format(end_time - start_time)if __name__=="__main__":main()
执行结果如下:
Total time:12.7875118256
from threading import Thread
import time
def my_counter():i = 0for _ in range(100000000):i = i+1return True
def main():thread_array = {}start_time = time.time()for tid in range(2):t = Thread(target=my_counter())t.start()thread_array[tid] = tfor i in range(2):thread_array[i].join()#以多进程、并发的方式运行两次my_counter函数end_time = time.time()print("Total time:{}").format(end_time - start_time)if __name__=="__main__":main()
执行结果如下:
Total time:15.8216409683
上述两个例子的结果发现:单线程运行两次函数的时间 要比 两个线程同时运行函数的时间短(仅限于本例)。
(4) fork操作:
调用一次,返回两次。因为操作系统自动把当前进程(称为父 进程)复制了一份(称为子进程),然后分别在父进程和子进 程内返回。子进程永远返回0,而父进程返回子进程的ID。子 进程只需要调用getppid()就可以拿到父进程的ID。
例:
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())
else:print 'I (%s) just created a child process (%s).' % (os.getpid(),pid)
执行结果如下:
Process (16480) start ...
I (16480) just created a child process (16481).
I am child process (16481) and my parent is (16480)
(5) multiprocessing是跨平台版本的多进程模块,它提供了一个Process类来代表一个进程对象,下面是示例代码:
from multiprocessing import Process
import time
def f(n):time.sleep(1)print n*nif __name__=="__main__":for i in range(10):p=Process(target=f,args=[i,])p.start()#使用多进程并发的方式执行函数f
这个程序如果用单进程写则需要执行10秒以上的时间, 而用多进程则启动10个进程并行执行,只需要用1秒多的时间。多进程时,每个进程各自有各自的GIL。而同一进程中的多线程受到GIL的影响,效率返而会下降。
(6) Queue是多进程安全的队列,可以使用Queue实现多进程之间的数据传递
from multiprocessing import Process,Queue
import time
def write(q):for i in ['A','B','C','D','E']:print ('Put %s to queue' % i)q.put(i)time.sleep(0.5)def read(q):while True:v = q.get(True)print('get %s from queue' %v)if __name__ == '__main__':q = Queue()pw = Process(target=write,args=(q,))pr = Process(target=read,args=(q,))pw.start()pr.start()pr.join()pr.terminate()
输出结果:
Put A to queue
get A from queue
Put B to queue
get B from queue
Put C to queue
get C from queue
Put D to queue
get D from queue
Put E to queue
get E from queue
(7) 进程池pool , 用于批量创建子进程,可以灵活控制子进程的数量
from multiprocessing import Pool
import time
def f(x):print x*xtime.sleep(2)return x*x
if __name__ == '__main__':pool = Pool(processes=5)res_list = []for i in range(10): res = pool.apply_async(f,[i,])''' 以异步并行的方式启动进程处理函数f,如果要同步等待的方式,可以在每次进程启动之后调用res.get()方法,也可以使用Pool.apply'''print('-------:',i)res_list.append(res)pool.close()pool.join()for r in res_list:print 'result',(r.get(timeout=5))
输出结果如下:
('-------:', 0)
('-------:', 1)
('-------:', 2)
('-------:', 3)
('-------:', 4)
('0-------:', 5)
('-------:', 6)
('-------:', 7)
1
('-------:', 8)
('-------:', 9)
4
16
9
25
36
49
64
81
result 0
result 1
result 4
result 9
result 16
result 25
result 36
result 49
result 64
result 81
如果使用同步方式,处理函数时 必须等待 前一个处理的结束,所以如果将该程序换为同步方式,输出结果则是顺序的。
(8) 多进程与多线程的对比:
from multiprocessing import Process
import threading
import time
lock = threading.Lock()
def run(info_list,n):lock.acquire()info_list.append(n)lock.release()print('%s' % info_list)
if __name__ == '__main__':info = []for i in range(10):p = Process(target=run,args=[info,i])p.start()p.join()time.sleep(1)print('-----------------threading--------------')for i in range(10):p = threading.Thread(target=run,args=[info,i])p.start()p.join()
输出结果为:
[0]
[1]
[2]
[3]
[4]
[5]
[6]
[7]
[8]
[9]
-----------------threading--------------
[0]
[0, 1]
[0, 1, 2]
[0, 1, 2, 3]
[0, 1, 2, 3, 4]
[0, 1, 2, 3, 4, 5]
[0, 1, 2, 3, 4, 5, 6]
[0, 1, 2, 3, 4, 5, 6, 7]
[0, 1, 2, 3, 4, 5, 6, 7, 8]
[0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
多进程间数据不能直接共享,每次处理函数run的结果都不能继承。而多线程间数据可以共享,但受到GIL的影响,run函数中在将数据追加到列表时,使用lock锁,追回完毕再释放lock,这样避免冲突。
转载于:https://blog.51cto.com/caiyuanji/1966279
MultiProcess-MultiThread相关推荐
- 压力测试衡量CPU的三个指标
压力测试衡量CPU的三个指标:CPU Utilization.Load Average和ContextSwitch Rate 上篇讲如何用LoadRunner监控Linux的性能指标,但是关于CPU的 ...
- redmine mysql 优化_Redmine性能优化方案
redmine服务器性能问题排查与优化建议: 以下建议的方案是基于redmine运行期的log文件中的render耗时.activerecord耗时,linux系统性能指标采样与 mysql 性能指标 ...
- Tibero与Oracle的优劣
要想知道Tibero与Oracle的优劣,那么首先要了解一下Tibero数据库 1.TIBERO 介绍 当前企业的业务随着数据的快速增加和系统环境的不断变化而迅速扩张,随着新的业务环境的增加,需要有更 ...
- 压力测试衡量CPU的三个指标:CPU Utilization、Load Average和Context Switch Rate
上篇讲如何用LoadRunner监控Linux的性能指标 ,但是关于CPU的几个指标没有搞清楚,下面就详细说说. CPU Utilization 好理解,就是CPU的利用率,75%以上就比较高了(也有 ...
- 衡量CPU的三个指标:CPU Utilization、Load Average和Context Switch Rate
CPU Utilization 好理解,就是CPU的利用率,75%以上就比较高了(也有说法是80%或者更高).除了这个指标外,还要结合Load Average和Context Switch Rate来 ...
- 压力测试衡量CPU的三个指标CPU Utilization、Load Average和ContextSwitch Rate
压力测试衡量CPU的三个指标:CPU Utilization.Load Average和ContextSwitch Rate 上篇讲如何用LoadRunner监控Linux的性能指标,但是关于CPU的 ...
- Python multiprocess 多进程模块
转发:http://www.langzi.fun/Python multiprocess 多进程模块.html 需要注意的是,如果使用多线程,用法一定要加上if __name__=='__main__ ...
- python 并行计算 并行方法总结 concurrent.futures pp pathos multiprocessing multiprocess模块 总结对比
目录 模块介绍文章 相近模块 1.按并行分类 (1)阻塞(非并行) (2)批次并行 (3)异步 2.按传参分类 (1)单个任务,任务多参数 (2)多个任务,任务单参数 (3)多个任务,任务多参数 3. ...
- python 并行计算 multiprocessing、multiprocess模块 简介
目录 多进程才是真·并行 multiprocessing模块 1.创建子进程 2.进程间通信--数据共享 3.进程间通信--数据传递 4.锁(同步原语) 5.其他重要函数 multiprocess模块 ...
- Debug Multithread DLL 与 Debug Multithread
在昨日的项目中,更新了其他人的Source与Project文件之后,程序运行总是抛出异常.跟踪调试的结果是一处内存释放引起的异常,但是明显感觉这不是导致问题的真正原因.所以在项目配置方面进行了比较,发 ...
最新文章
- 学习笔记(十七)——redis(CRUD)
- 百度搜索结果 转换_如何让图片出现在百度搜索结果里出现?
- python csv文件参数化_Python 读取csv文件的某一列数据,并定义两个pattern,确定变化区间...
- nginx开发从入门到精通 http://tengine.taobao.org/book/
- MyBatis 架构分层与模块划分-基础支持层
- fedora 15怎么修改运行级别?
- 嵌入式wifi 芯片 推荐_人工智能对汽车芯片设计的影响
- 7-36 并查集【模板】 (10 分)
- 【noi】植物大战僵尸
- C语言课后习题(26)
- java数青蛙_『字节跳动LeetCode联合周赛』--周赛185(JavaScript) | OFEII
- mac终端配置Android ADB命令
- JavaScript 工作原理之二-如何在 V8 引擎中书写最优代码的 5 条小技巧(译)
- 【宽度优先搜索笔记】BFS输出最短路径
- MongoDB 通过 Java 代码 批量操作
- 【深入理解JS核心技术】13. 什么是高阶函数
- 模2运算的加减乘除运算
- soundpool android,android – 如何获取Soundpool的持续时间
- 就这一篇:教你真正有效地解决爆满的C盘!
- 布谷技术月刊 1608