上下文管理、线程池、redis订阅和发布
一:上下文管理:
对于一些对象在使用之后,需要关闭操作的。比如说:socket、mysql数据库连接、文件句柄等。
都可以用上下文来管理。
语法结构:
Typical usage: @contextmanager
def some_generator(<arguments>):
<setup>
try:
yield <value>
finally:
<cleanup> This makes this: with some_generator(<arguments>) as <variable>:
<body>
code:
import socket
import contextlib @contextlib.contextmanager
def sock_server(host,port):
sk=socket.socket()
sk.bind((host,port))
sk.listen()
try:
yield sk
finally:
sk.close() with sock_server("127.0.0.1",) as soc:
print(soc)
执行顺序:
aaarticlea/png;base64,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" alt="" />
解释:python从上到下依次解释:
1、当到with的时候,执行with内socket_server("127.0.0.1",),跳到
2、被contextlib.contextmanager装饰的函数。
3、依次执行函数socket_server到yield 并把sk返回给第4步的sco变量
4、然后执行with下面的代码块,执行print语句。
5、当with语句的代码块执行完。跳到第3步的yeild。
6、执行finally语句里的代码块。
二:线程池(threadpool)
自己版本:
#!/bin/env python
#author:evil_liu
#date:--
#description: thread pool import threading
import time
import queue class Thread_Poll:
'''
功能:该类主要实现多线程,以及线程复用。
'''
def __init__(self,task_num,max_size):
'''
功能:该函数是初始化线程池对象。
:param task_num: 任务数量。
:param max_size: 线程数量。
:return:无。
'''
self.task_num=task_num
self.max_size=max_size
self.q=queue.Queue(task_num)#设置任务队列的。
self.thread_list=[]
self.res_q=queue.Queue()#设置结果队列。 def run(self,func,i,call_back=None):
'''
功能:该函数是线程池运行主函数。
:param func: 传入任务主函数。
:param *args: 任务函数参数,需要是元组形式。
:param call_back: 回调函数。
:return: 无。
'''
if len(self.thread_list)<self.max_size:#如果目前线程数小于我们定义的线程的个数,进行创建。
self.creat_thread()
misson=(func,i,call_back)#往任务队列放任务。
self.q.put(misson) def creat_thread(self):
'''
功能:该函数主要是创建线程,并调用call方法。
:return: 无。
'''
t=threading.Thread(target=self.call)#创建线程
t.start() def call(self):
'''
功能:该函数是线程循环执行任务函数。
:return: 无。
'''
cur_thread=threading.currentThread
self.thread_list.append(cur_thread)
event=self.q.get()
while True:
func,args,cal_ba=event#获取任务函数。
try:
res=func(*args)#执行任务函数。注意参数形式是元组形式。
flag="OK"
except Exception as e:
print(e)
res=False
flag="fail"
self.res(res,flag)#调用回调函数,将执行结果返回到队列中。
try:
event=self.q.get(timeout=)#如果任务队列为空,获取任务超时2s超过2s线程停止执行任务,并退出。
except Exception:
self.thread_list.remove(cur_thread)
break
def res(self,res,status):
'''
功能:该方法主要是将执行结果方法队列中。
:param res: 任务函数的执行结果。
:param status: 执行任务函数的结果,成功还是失败。
:return: 无。
'''
da_res=(res,status)
self.res_q.put(da_res) def task(x,y):
'''
功能:该函数主要需要执行函数。
:param x: 参数。
:return: 返回值1,表示执行成功。
'''
print(x)
return x+y
def wri_fil(x):
'''
功能:该函数主要讲结果队列中的结果写入文件中。
:param x: 任务长度。
:return: 无。
'''
while True:#将执行结果,从队列中获取结果并将结果写入文件中。
time.sleep()
if pool.res_q.qsize()==x:#当队列当前的长度等于任务执行次数,表示任务执行完成。
with open('1.txt','w') as f1:
for i in range(pool.res_q.qsize()):
try:
data=pool.res_q.get(timeout=)
f1.write('mission result:%s,status:%s\n'%data)
except Exception:
break
break
else:
continue
if __name__ == '__main__':
pool=Thread_Poll(,)#初始化线程池对象。
for i in range():#循环任务。
pool.run(task,(,))
wri_fil()
老师版本:注意老师在创建线程的时候,如果此时任务队列中没有任务的时候,不会创建其他线程。在线程执行完任务之后,将线程加入空闲线程的列表中,然后让当前线程去队列里获取任务,利用queue里的get()方法阻塞的作用的,如果一直阻塞的话,
然后表示空闲的列表中的加入的线程 一直有,此时表示创建线程数已经满足任务需求,如果不阻塞则空闲线程列表里没有空余线程。而是获取任务,执行任务。
#!/usr/bin/env python
# -*- coding:utf- -*- import queue
import threading
import contextlib
import time StopEvent = object() class ThreadPool(object): def __init__(self, max_num, max_task_num = None):
if max_task_num:
self.q = queue.Queue(max_task_num)
else:
self.q = queue.Queue()
self.max_num = max_num
self.cancel = False
self.terminal = False
self.generate_list = []
self.free_list = [] def run(self, func, args, callback=None):
"""
线程池执行一个任务
:param func: 任务函数
:param args: 任务函数所需参数
:param callback: 任务执行失败或成功后执行的回调函数,回调函数有两个参数1、任务函数执行状态;、任务函数返回值(默认为None,即:不执行回调函数)
:return: 如果线程池已经终止,则返回True否则None
"""
if self.cancel:
return
if len(self.free_list) == and len(self.generate_list) < self.max_num:
self.generate_thread()
w = (func, args, callback,)
self.q.put(w) def generate_thread(self):
"""
创建一个线程
"""
t = threading.Thread(target=self.call)
t.start() def call(self):
"""
循环去获取任务函数并执行任务函数
"""
current_thread = threading.currentThread()
self.generate_list.append(current_thread) event = self.q.get()
while event != StopEvent: func, arguments, callback = event
try:
result = func(*arguments)
success = True
except Exception as e:
success = False
result = None if callback is not None:
try:
callback(success, result)
except Exception as e:
pass with self.worker_state(self.free_list, current_thread):
if self.terminal:
event = StopEvent
else:
event = self.q.get()
else: self.generate_list.remove(current_thread) def close(self):
"""
执行完所有的任务后,所有线程停止
"""
self.cancel = True
full_size = len(self.generate_list)
while full_size:
self.q.put(StopEvent)
full_size -= def terminate(self):
"""
无论是否还有任务,终止线程
"""
self.terminal = True while self.generate_list:
self.q.put(StopEvent) self.q.queue.clear() @contextlib.contextmanager
def worker_state(self, state_list, worker_thread):
"""
用于记录线程中正在等待的线程数
"""
state_list.append(worker_thread)
try:
yield
finally:
state_list.remove(worker_thread) # How to use pool = ThreadPool() def callback(status, result):
# status, execute action status
# result, execute action return value
pass def action(i):
print(i) for i in range():
ret = pool.run(action, (i,), callback) time.sleep()
print(len(pool.generate_list), len(pool.free_list))
print(len(pool.generate_list), len(pool.free_list))
# pool.close()
# pool.terminate()
上下文管理、线程池、redis订阅和发布的更多相关文章
- C# 多线程的自动管理(线程池) 基于Task的方式
C# 多线程的自动管理(线程池) 在多线程的程序中,经常会出现两种情况: 1. 应用程序中线程把大部分的时间花费在等待状态,等待某个事件发生,然后给予响应.这一般使用 ThreadPool(线程 ...
- Redis订阅和发布模式和Redis事务
-------------------Redis订阅和发布模式------------------- 1.概念 Redis 发布订阅(pub/sub)是一种消息通信模式: 发送者(pu ...
- redis订阅与发布系统
一.概述 1.redis通过publish.subscribe等命令实现了订阅与发布模式. 2.这个功能提供两种信息机制,分别是订阅/发布到频道和订阅/发布到模式. 二.频道的订阅与信息发送 1.re ...
- 使用ExecutorCompletionService 管理线程池处理任务的返回结果
在我们日常使用线程池的时候,经常会有需要获得线程处理结果的时候.此时我们通常有两种做法. 1. 使用并发容器将callable.call() 的返回Future存储起来.然后使用一个消费者线程去遍历这 ...
- redis 订阅与发布
PUBLISH,SUBSCRIBE,等命令实现订阅与发布 订阅/发布到频道 订阅/发布到模式 频道的订阅与信息发送 订阅subscribe,可以让客户端订阅任意数量的频道, 每当有新信息发送到 ...
- Redis订阅与发布
发布与订阅模型在许多编程语言中都有实现,也就是我们经常说的设计模式中的一种--观察者模式.在一些应用场合,例如发送方并不是以固定频率发送消息,如果接收方频繁去咨询发送方,这种操作无疑是很麻烦并且不友好 ...
- redis订阅与发布(把redis作为消息中间件)
订阅频道127.0.0.1:6379> subscribe chat1Reading messages... (press Ctrl-C to quit)1) "subscribe&q ...
- C#多线程学习(四) 多线程的自动管理(线程池)
在多线程的程序中,经常会出现两种情况: 一种情况: 应用程序中,线程把大部分的时间花费在等待状态,等待某个事件发生,然后才能给予响应 这一般使用ThreadPo ...
- PHP swoole实现redis订阅和发布
前戏:实现用户下单,服务器通知后台接收订单...类似美团外卖 1.首先要实现一个订阅程序 $result = $client->connect('127.0.0.1', 6379, functi ...
随机推荐
- [SHTSC 2007] 善意的投票
我就是来复习Dinic算法的,仅10天不写,我已经退化成写一遍+调试需要接近一个小时了,当然其中不乏在网上乱逛的时间… 赞成从S源点连一条单向边,反对向T汇点连一条单向边,朋友关系连双向边. 但是总感 ...
- BSS段 data段 text段 堆heap 和 栈stack
BSS段:BSS段(bss segment)通常是指用来存放程序中未初始化的全局变量的一块内存区域.BSS是英文Block Started by Symbol的简称.BSS段属于静态内存分配. 数 ...
- C++小项目:directx11图形程序(八):particleSysclass
粒子系统类,粒子系统是游戏里细小元素的控制系统,虽然感觉上它对游戏的影响不大,但是其实有了它能给游戏增色不少.粒子系统控制着细小元素的生死,运动,纹理.对它的编写让我知道,游戏里的这一片从天空飘落的雪 ...
- php 的txt操作,加入类容
<?php $fr=fopen("./data/test.txt",'a'); //fopen(位置,打开方式) if(!$fr) { echo " error&q ...
- linux内核学习之四 系统调用
一 概念区分 提到linux系统调用,不得不区分几个比较容易混淆的概念: 系统调用:系统调用就是一种特殊的接口.通过这个接口,用户可以访问内核空间.系统调用规定了用户进程进入内核的具体位置. 应用程 ...
- Html标签第二课css
css(Cascading Style Sheet)叠层样式表.用于控制网页样式并允许将样式信息与网页内容分离的一种标记性语言. 一:样式三种控制方法 1.行内样式: <div style=& ...
- Angular JS的模块依赖
AngularJS是纯客户端技术,完全用Javascript编写的.它使用的是网页开发的常规技术(HTML,CSS,Javascript),目的是让网页应用开发更快更容易. AngularJS简化应用 ...
- Socket模块学习
Socket是什么呢? Socket是应用层与TCP/IP协议族通信的中间软件抽象层,它是一组接口.在设计模式中,Socket其实就是一个门面模式,它把复杂的TCP/IP协议族隐藏在Socke ...
- Sql Server 查看表修改记录
可以尝试如下建议:1.可以使用默认的Log工具或者第三方的(比如:LiteSpeed)的工具.2.做Trace机制,下次出现问题可以溯源.3.一个简单的办法: --Step #1: USE DBNam ...
- FB
转眼间,开始工作到现在好几年,忙着功能,忙着补漏填坑,忙着项目,现在回顾着开始的理想,一时有点恍惚,然后鄙视了下自己居然还在“理想”中…… 那就开始吧,做点什么呢? DX9/DX11的支持是必须的,S ...