上下文管理、线程池、redis订阅和发布

时间:2024-01-01 19:54:51

一:上下文管理:

对于一些对象在使用之后,需要关闭操作的。比如说: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()