Python实现生产者消费者、装饰器模式

生产者-消费模式

Python通常使用 阻塞队列 实现 生产者-消费者模式计算后端Trace系统 使用了这一模式,类似如下:

# -*- coding: UTF-8 -*-
import eventlet
from eventlet import queue

# pool 和 q 的大小可以动态调整
pool = eventlet.GreenPool(size=5)
q = queue.Queue(maxsize=3)


def producer(idx):
    item = "数据-%s" % idx
    # 每次调用 put() 时,unfinished_tasks 计数器加 1
    q.put(item)
    print("生产: %s" % item)
    eventlet.sleep(0.1)
    # 发送终止信号(有几个消费者就发几个)
    q.put(None)


def consumer(idx):
    while True:
        item = q.get()
        if item is None:  # 收到终止信号
            # 每次调用 task_done() 时,unfinished_tasks 计数器减 1
            # q.task_done()
            print("消费者-%s 退出" % idx)
            break
        print("消费: %s (由消费者-%s处理)" % (item, idx))
        # q.task_done()
        eventlet.sleep(0.3)


# 启动生产者和消费者
for i in range(3):
    pool.spawn_n(producer, i)
for i in range(3):
    pool.spawn_n(consumer, i)

# join() 会阻塞直到 unfinished_tasks 变为 0
# q.join()
# print("所有任务完成")

# 等待所有协程完成(可选,join() 后通常已无活跃协程)
pool.waitall()

print("所有任务完成")

装饰器模式

计算后端Trace系统 使用了装饰模式实现 trace信息采集器,类似如下:

import functools
import sys
from abc import ABC

# trace信息采集装饰器
def trace(service):
    def decorator(func):
        # functools.wraps(func) 会将原函数(func)的 __name__、__doc__、__module__ 等属性复制到包装函数(wrapper)上。
        @functools.wraps(func)
        def wrapper(*args, **kwargs):
            # 前置逻辑:模拟构建追踪上下文
            print("build trace info for %s" % service.name)
            
            try:
                # 执行原函数
                return func(*args, **kwargs)
            except Exception as e:
                # 异常处理
                print("catch err: %s" % str(e))
                raise e
            finally:
                # 后置逻辑:模拟上传日志
                print("upload to skywalking")
                
        return wrapper
    return decorator

# 使用装饰器
@trace(service=sc.Component.NovaApi)
def rebuild_vm_in_nova_api():
    print("begin to rebuild instance")
    raise Exception("test err")

# 调用
rebuild_vm_in_nova_api()
posted @ 2025-07-03 16:16  如三月兮  阅读(12)  评论(0)    收藏  举报