python(进程池/线程池)
进程池
import multiprocessing
import time def do_calculation(data):
print(multiprocessing.current_process().name + " " + str(data))
time.sleep(3)
return data * 2 def start_process():
print ('Starting', multiprocessing.current_process().name) if __name__ == '__main__':
inputs = list(range(10))
print ('Input :' + str(inputs)) pool_size = multiprocessing.cpu_count()
pool = multiprocessing.Pool(processes=pool_size,
initializer=start_process,
)
#more inputs
#more_inputs = [11,12,13,14,15,16,17,18,19,20]
#pool_outputs = pool.map(do_calculation, more_inputs) pool_outputs = pool.map(do_calculation, inputs)
pool.close() # no more tasks
pool.join() # wrap up current tasks print ('Pool :' + str(pool_outputs))
运行如下:
root # python pool.py
Input :[0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
('Starting', 'PoolWorker-1')
PoolWorker-1 0
('Starting', 'PoolWorker-2')
PoolWorker-2 2
PoolWorker-1 1
PoolWorker-2 3
PoolWorker-1 4
PoolWorker-2 6
PoolWorker-1 5
PoolWorker-2 7
PoolWorker-1 8
PoolWorker-1 9
Pool :[0, 2, 4, 6, 8, 10, 12, 14, 16, 18]
如果任务是动态添加可以用如下代码
import multiprocessing
import time def worker(data):
if data == 3:
time.sleep(10)
else:
time.sleep(1)
print(multiprocessing.current_process().name + " " + str(data))
return data * 2 def start_process():
print ('Starting', multiprocessing.current_process().name) #callback func
def say(res):
print res if __name__ == '__main__':
inputs = list(range(10))
print ('Input :' + str(inputs)) pool_size = multiprocessing.cpu_count()
pool = multiprocessing.Pool(processes=pool_size,
initializer=start_process,
) for i in inputs:
pool.apply_async(worker, (i,))
#pool.apply_async(worker, (i,), callback=say) pool.close() # no more tasks
pool.join() # wrap up current tasks
输出如下:
root # python pool2.py
Input :[0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
('Starting', 'PoolWorker-1')
('Starting', 'PoolWorker-2')
PoolWorker-1 0
PoolWorker-2 1
PoolWorker-1 2
PoolWorker-1 4
PoolWorker-1 5
PoolWorker-1 6
PoolWorker-1 7
PoolWorker-1 8
PoolWorker-1 9
PoolWorker-2 3
线程池
import Queue
import sys
import threading
import time thread_count = 2
mutex = threading.Lock() class MyThread(threading.Thread):
def __init__(self, workQueue, resultQueue,timeout=0, **kwargs):
threading.Thread.__init__(self, kwargs=kwargs)
self.timeout = 1
self.setDaemon(True)
self.workQueue = workQueue
self.resultQueue = resultQueue
self.start() def run(self):
while True:
try:
callable, args, kwargs = self.workQueue.get(timeout=self.timeout)
res = callable(args, self.getName())
self.resultQueue.put(res) except Queue.Empty:
break
except :
print sys.exc_info()
raise class ThreadPool:
def __init__( self, num_of_threads=10):
self.workQueue = Queue.Queue()
self.resultQueue = Queue.Queue()
self.threads = []
self.__createThreadPool( num_of_threads ) def __createThreadPool( self, num_of_threads ):
for i in range( num_of_threads ):
thread = MyThread( self.workQueue, self.resultQueue )
self.threads.append(thread) def wait_for_complete(self):
while len(self.threads):
thread = self.threads.pop()
if thread.isAlive():
thread.join() def add_job( self, callable, args, **kwargs ):
while True:
if self.workQueue.qsize() < 10000:
self.workQueue.put( (callable,args,kwargs) )
break
time.sleep(0.1) def worker(data, threadid): if mutex.acquire(1):
print threadid, data
mutex.release() time.sleep(3)
return data * 2 if __name__ == '__main__': threadPool = ThreadPool(thread_count)
for i in range(10):
threadPool.add_job(worker, i) threadPool.wait_for_complete()
print 'result Queue\'s length == %d '% threadPool.resultQueue.qsize()
while threadPool.resultQueue.qsize():
print threadPool.resultQueue.get()
print 'end testing'
运行如下:
root # python g.py
Thread-1 0
Thread-2 1
Thread-1 2
Thread-2 3
Thread-1 4
Thread-2 5
Thread-1 6
Thread-2 7
Thread-1 8
Thread-2 9
result Queue's length == 10
0
2
4
6
8
10
12
14
16
18
end testing
简单测试了一下,如果worker函数需要做大量耗cpu的运算,用进程池速度比线程池快数倍。
2.492s VS 0.598s
python(进程池/线程池)的更多相关文章
- python并发编程-进程池线程池-协程-I/O模型-04
目录 进程池线程池的使用***** 进程池/线程池的创建和提交回调 验证复用池子里的线程或进程 异步回调机制 通过闭包给回调函数添加额外参数(扩展) 协程*** 概念回顾(协程这里再理一下) 如何实现 ...
- Python学习之GIL&进程池/线程池
8.6 GIL锁** Global interpreter Lock 全局解释器锁 实际就是一把解释器级的互斥锁 In CPython, the global interpreter lock, or ...
- Python并发编程05 /死锁现象、递归锁、信号量、GIL锁、计算密集型/IO密集型效率验证、进程池/线程池
Python并发编程05 /死锁现象.递归锁.信号量.GIL锁.计算密集型/IO密集型效率验证.进程池/线程池 目录 Python并发编程05 /死锁现象.递归锁.信号量.GIL锁.计算密集型/IO密 ...
- Python标准模块--concurrent.futures 进程池线程池终极用法
concurrent.futures 这个模块是异步调用的机制concurrent.futures 提交任务都是用submitfor + submit 多个任务的提交shutdown 是等效于Pool ...
- concurrent.futures模块(进程池/线程池)
需要注意一下不能无限的开进程,不能无限的开线程最常用的就是开进程池,开线程池.其中回调函数非常重要回调函数其实可以作为一种编程思想,谁好了谁就去掉 只要你用并发,就会有锁的问题,但是你不能一直去自己加 ...
- Python-GIL 进程池 线程池
5.GIL vs 互斥锁(*****) 1.什么是GIL(Global Interpreter Lock) GIL是全局解释器锁,是加到解释器身上的,保护的就是解释器级别的数据 (比如垃圾回收的数据) ...
- 13 并发编程-(线程)-异步调用与回调机制&进程池线程池小练习
#提交任务的两种方式 #1.同步调用:提交完任务后,就在原地等待任务执行完毕,拿到结果,再执行下一行代码,导致程序是串行执行 一.提交任务的两种方式 1.同步调用:提交任务后,就在原地等待任务完毕,拿 ...
- python day 20: 线程池与协程,多进程TCP服务器
目录 python day 20: 线程池与协程 2. 线程 3. 进程 4. 协程:gevent模块,又叫微线程 5. 扩展 6. 自定义线程池 7. 实现多进程TCP服务器 8. 实现多线程TCP ...
- Python之路——线程池
1 线程基础 1.1 线程状态 线程有5种状态,状态转换的过程如下图所示: 1.2 线程同步——锁 多线程的优势在于可以同时运行多个任务(至少感觉起来是这样,其实Python中是伪多线程).但是当线程 ...
- 并发编程---线程queue---进程池线程池---异部调用(回调机制)
线程 队列:先进先出 堆栈:后进先出 优先级:数字越小优先级越大,越先输出 import queue q = queue.Queue(3) # 先进先出-->队列 q.put('first') ...
随机推荐
- JavaEE学习之设计模式
转自:http://mp.weixin.qq.com/s?__biz=MjM5OTMxMzA4NQ==&mid=221913387&idx=2&sn=d5d006300722f ...
- windows7下,protel 99se元件库加载问题的解决方案
方法一:到C盘(系统盘),系统文件夹(c:\windows)下的ADVPCB99SE和ADVSch99SE文件先配置原理图,用本文打开ADVPCB99SE文件,在[Change Library Fil ...
- sqlite 查询数据 不用回调
int main( void ){ sqlite3 *db=NULL; char *zErrMsg = 0; int rc; //打开数据库连接 rc = sqlite3 ...
- 《Java4Android视频教程》学习笔记(二)
一:面向对象 1.对象 ①对象的使用方法 对象.变量 对象.方法 ②匿名对象 new A().方法 new A().变量 匿名对象会被分配到对内存中 java内存处理机制会对一定时间内无指针指向的对象 ...
- Uber 司机有话说:你以为当个 Uber 司机很轻松?大错特错!
Uber 最近的负面新闻越来越多.各方成员都在抨击.斥责.揭露 Uber 公司的各种黑幕.今天,来自 Uber 公司的司机为您讲述咱「拼车老司机」自己的故事.你以为开着自己的私家车出去满城市的晃悠接客 ...
- 基于mini2440的看门狗(裸机)
在由单片机构成的微型计算机系统中,由于单片机的工作常常会受到来自外界电磁场的干扰,造成程序的跑飞,而陷入死循环,程序的正常运行被打断,由单片机控制的系统无法继续工作,会造成整个系统的陷入停滞状态,发生 ...
- 文件上传下载样式 --- bootstrap
在平时工作中,文件上传下载功能属于不可或缺的一部分.bootstrap前端样式框架也使用的比较多,现在根据bootstrap强大的样式模板,自定义一种文件下载的样式. 后续会使用spring MVC框 ...
- C# 获得当前应用程序路径
1.获得当前应用程序的路径最稳定的方法:AppDomain.CurrentDomain.BaseDirectory 生成的路径:../项目名称/bin/Debug下的路径
- Android数据的四种存储方式SharedPreferences、SQLite、Content Provider和File (四) —— ContentProvider
ContentProvider是安卓平台中,在不同应用程序之间实现数据共享的一种机制.一个应用程序如果需要让别的程序可以操作自己的数据,即可采用这种机制.并且此种方式忽略了底层的数据存储实现,Cont ...
- Ubuntu_16.04_Lamp
Ubuntu_16.04安装Lamp开发环境 目录 安装Apache2 安装php5 安装mysql-server 安装php5-mysql(php使用mysql服务,包括mysql,mysqli,m ...