python_进程池以及线程池
可以重复利用的线程
直接上代码
from threading import Thread, current_thread
from queue import Queue
# 重写线程类
class MyThread(Thread):
def __init__(self):
super().__init__()
self.daemon = True # 守护线程
self.queue = Queue(10)
self.start() # 实例化的时候开启线程 def run(self): # 子线程只有这一个线程, 从队列里面拿任务
while True:
task, args, kwargs = self.queue.get() # 拿任务 也是元组
task(*args, **kwargs) # 可能有,可能没有,所有传入不定长参数
self.queue.task_done() # 结束任务 def apply_async(self, func, args=(), kwargs={}): # 自写任务,不是重写任务, 充当生产者, 给线程提供任务(把任务扔到队列)
self.queue.put((func, args, kwargs)) def join_R(self): # 主线程等待子线程结束
self.queue.join() # task_done 为0 的时候就阻塞 def func():
print(1, current_thread()) def func2(*args, **kwargs):
print(2, current_thread())
print('func: ', args, kwargs) t = MyThread()
t.apply_async(func)
t.apply_async(func2, args=(1,2), kwargs={'a':1, 'b':2})
print("任务提交完成")
t.join_R()
print("任务完成")
结果:
任务提交完成
1 <MyThread(Thread-1, started daemon -1223214272)>
2 <MyThread(Thread-1, started daemon -1223214272)>
func: (1, 2) {'a': 1, 'b': 2}
任务完成 任务完成后,主线程就开始退出, 因此守护线程被杀死
线程池的简单实现
池的概念

主线程: 相当于生产者,只管向线程池提交任务。
并不关心线程池是如何执行任务的。
因此,并不关心是哪一个线程执行的这个任务。
线程池: 相当于消费者,负责接收任务,
并将任务分配到一个空闲的线程中去执行。
代码实现如下:
from threading import Thread, current_thread
from queue import Queue class T_pool:
def __init__(self, n): # 准备多少个池
super().__init__()
self.queue = Queue()
for i in range(n): # 在池里开多少个线程
Thread(target=self.fun, daemon=Thread).start() # 守护进程 并启动 def fun(self): # 生产者
while True:
task = self.queue.get()
task()
self.queue.task_done() def apply_async(self, task): # 消费者
self.queue.put(task) def join(self):
self.queue.join() def func():
print(current_thread()) def func2():
print(current_thread()) p = T_pool(2)
p.apply_async(func)
p.apply_async(func2)
p.join()
结果:
<Thread(Thread-1, started daemon -1223324864)>
<Thread(Thread-1, started daemon -1223324864)>
Python自带的池
内置线程池
from multiprocessing.pool import ThreadPool # 线程池
from multiprocessing import pool # 进程池
# 内置线程池
def fun(*args, **kwargs):
print(args, kwargs) p = ThreadPool(2) # 直接使用内置的
p.apply_async(fun, args=(1,2), kwds={'a':1})
p.close() # 要求:在join前必须要close,这样就不允许再提交任务了
p.join()
结果:
(1, 2) {'a': 1}
内置进程池
from multiprocessing import Pool # 进程池
# 内置进程池
def fun(*args, **kwargs):
print(args, kwargs) if __name__ == '__main__': # 必须要有一个main测试
p = Pool(2) # pool的实例化必须在main测试之下
p.apply_async(fun, args=(1,2), kwds={'a':1})
p.close() # 要求:在join前必须要close,这样就不允许再提交任务了
p.join()
结果:
(1, 2) {'a': 1}
池的其他操作
操作一: close - 关闭提交通道,不允许再提交任务
操作二: terminate - 中止进程池,中止所有任务
操作三: 结果操作
结果操作
from multiprocessing.pool import ThreadPool
import time
def func(n):
if n == 1:
return 1
elif n == 2:
return 2
return func(n-1) + func(n-2) pool = ThreadPool() a_result = pool.apply_async(func, args=(35,))
print("note1:",time.asctime(time.localtime(time.time())))
result = a_result.get() # 会阻塞,知道结果产生了
print("note2:",time.asctime(time.localtime(time.time())))
结果:
note1: Mon Sep 17 00:07:31 2018
note2: Mon Sep 17 00:07:34 2018
使用池来实现并发服务器
使用线程池来实现并发服务器
import socket
from multiprocessing.pool import ThreadPool # 线程池
from multiprocessing import Pool, cpu_count
'''
使用线程池来实现
并发服务器
'''
print(cpu_count()) server = socket.socket()
server.bind(('0.0.0.0', 8080))
server.listen(1000) def work_thread(conn):
while True:
data = conn.recv(1000)
if data:
print(data)
conn.send(data) else:
conn.close()
break if __name__ == '__main__': t_pool = ThreadPool(5) # 使用线程池, 通常分配2倍的cpu个数
while True:
conn,addr = server.accept()
t_pool.apply_async(work_thread, args=(conn,)) # 接收的是个任务, conn做为参数
使用进程池来实现并发服务器
import socket
from multiprocessing.pool import ThreadPool # 线程池
from multiprocessing import Pool, cpu_count
'''
使用进程池来实现
并发服务器
'''
print(cpu_count()) server = socket.socket()
server.bind(('0.0.0.0', 9000))
server.listen(1000) def work_process(server):
t_pool = ThreadPool(cpu_count()*2) # 使用线程池, 通常分配2倍的cpu个数
while True:
conn,addr = server.accept()
t_pool.apply_async(work_thread, args=(conn,)) # 接收的是个任务, conn做为参数 def work_thread(conn):
while True:
data = conn.recv(1000)
if data:
print(data)
conn.send(data) else:
conn.close()
break n = cpu_count() # 获取当前计算机的CPU核心数量
p = Pool(n)
for i in range(n): # 充分利用CPU, 为每个CPU分配一个进程
p.apply_async(work_process, args=(server,)) p.close()
p.join()
客户端:
import socket click = socket.socket()
click.connect(('127.0.0.1', 8888)) while True:
data = input("请输入你要发送的数据:")
click.send(data.encode())
print("接收到的消息: {}".format(click.recv(1024).decode()))
总结完毕。
作者:含笑半步颠√
博客链接:https://www.cnblogs.com/lixy-88428977
声明:本文为博主学习感悟总结,水平有限,如果不当,欢迎指正。如果您认为还不错,欢迎转载。转载与引用请注明作者及出处。
python_进程池以及线程池的更多相关文章
- python系列之 - 并发编程(进程池,线程池,协程)
需要注意一下不能无限的开进程,不能无限的开线程最常用的就是开进程池,开线程池.其中回调函数非常重要回调函数其实可以作为一种编程思想,谁好了谁就去掉 只要你用并发,就会有锁的问题,但是你不能一直去自己加 ...
- 第三十八天 GIL 进程池与线程池
今日内容: 1.GIL 全局解释器锁 2.Cpython解释器并发效率验证 3.线程互斥锁和GIL对比 4.进程池与线程池 一.全局解释器锁 1.GIL:全局解释器锁 GIL本质就是一把互斥锁,是夹在 ...
- python并发编程之进程池,线程池,协程
需要注意一下不能无限的开进程,不能无限的开线程最常用的就是开进程池,开线程池.其中回调函数非常重要回调函数其实可以作为一种编程思想,谁好了谁就去掉 只要你用并发,就会有锁的问题,但是你不能一直去自己加 ...
- 基于concurrent.futures的进程池 和线程池
concurrent.futures:是关于进程池 和 线程池 的 官方文档 https://docs.python.org/dev/library/concurrent.futures.html 现 ...
- GIL锁、进程池与线程池
1.什么是GIL? 官方解释: ''' In CPython, the global interpreter lock, or GIL, is a mutex that prevents multip ...
- python自带的进程池及线程池
进程池 """ python自带的进程池 """ from multiprocessing import Pool from time im ...
- 内存池、进程池、线程池介绍及线程池C++实现
本文转载于:https://blog.csdn.net/ywcpig/article/details/52557080 内存池 平常我们使用new.malloc在堆区申请一块内存,但由于每次申请的内存 ...
- python并发编程之进程池,线程池concurrent.futures
进程池与线程池 在刚开始学多进程或多线程时,我们迫不及待地基于多进程或多线程实现并发的套接字通信,然而这种实现方式的致命缺陷是:服务的开启的进程数或线程数都会随着并发的客户端数目地增多而增多, 这会对 ...
- python之进程池与线程池
一.进程池与线程池介绍 池子使用来限制并发的任务数目,限制我们的计算机在一个自己可承受的范围内去并发地执行任务 当并发的任务数远远超过了计算机的承受能力时,即无法一次性开启过多的进程数或线程数时就应该 ...
- 12 并发编程-(线程)-线程queue&进程池与线程池
queue 英 /kjuː/ 美 /kju/ 队列 1.class queue.Queue(maxsize=0) #队列:先进先出 import queue q=queue.Queue() q.put ...
随机推荐
- openjudge1.2
目录 1.2.1 1.2.2 1.2.3 1.2.4 1.2.5 1.2.6 1.2.7 1.2.8 1.2.9 1.2.10 1.2.1 描述 分别定义int,short类型的变量各一个,并依次输出 ...
- 设计模式概要 & 六原则一法则
参考文章 http://blog.csdn.net/sinat_26342009/article/details/46419873 继承vs组合:http://www.cnblogs.com/feic ...
- Oracle之clob字段不能union的问题
原因:由于clob类型字段不能使用group by函数,而union中需要使用group by过滤掉重复纪录: 解决方法:union可以改为union all.
- python skimage图像处理(二)
python skimage图像处理(二) This blog is from: https://www.jianshu.com/p/66e6261f0279 图像简单滤波 对图像进行滤波,可以有两 ...
- NIO通信中connect()方法和finishConnect()方法的区别
1.对于阻塞模式下,调用connect()进行连接操作时,会一直阻塞到连接建立完成(无连接异常的情况下).所以可以不用finishConnect来确认. 2.但在非阻塞模式下,connect()操作是 ...
- Mini UI tree上万复杂节点加载缓慢处理设计
最直接的方式是设置tree顶级不展开,可以解决一定效率. expandOnLoad Boolean/Number 加载后是否展开.比如:true展开所有节点:0展开第一级节点.以此类推. 1. 解决问 ...
- 使用trace文件分析ANR
2017年02月07日 12:32:45 不死鸟JGC 阅读数 13886更多 分类专栏: Android 版权声明:本文为博主原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链 ...
- setTimeout的小尴尬
我们都知道,alert这种内置弹框会阻塞后续代码执行: 之所以如此,就是因为JavaScript代码在浏览器中是单线程执行的.换句话说,浏览器中只有一个主线程负责运行所有JavaScript代码(不考 ...
- QT5 编译提示 cannot find GL/gl.h ubuntu16.04
安装软件: sudo apt-get install mesa-common-dev sudo apt-get install libgl1-mesa-dev libglu1-mesa-dev
- EasyNVR摄像机网页无插件直播方案H5前端构建之:通道内部搜索功能的实现方案与代码
EasyNVR网页摄像机直播方案 EasyNVR是一款拥有完整.自主.可控知识产权,同时又能够具备软硬一体功能的安防互联网化流媒体服务器,能够通过简单的网络摄像机通道配置,将传统监控行业里面的高清网络 ...