第十章:使用进程、线程和协程提供并发性-asyncio:异步I/O、事件循环和并发工具-接收UNIX信号

10.5.13 接收UNIX信号
UNIX系统事件通知通常会中断一个应用,触发它们的处理器。结合asyncio使用时,信号处理器回调会与事件循环管理的其他协程和回调交叉执行。这种集成会更少地中断函数,尽可能减少提供防护来清理未完成的操作的需要。
信号处理器必须是常规的callable,而不是协程。

import asyncio
import functools
import os
import signal

def signal_handler(name):
    print('signal_handler({!r})'.format(name))

# 信号处理器用add_signal_handler()注册。第一个参数是信号;第二个参数是回调。不
# 向回调传递任何参数,所以如果需要参数,可以用functools.partial()包装一个函数。
event_loop = asyncio.get_event_loop()

event_loop.add_signal_handler(
    signal.SIGHUP,
    functools.partial(signal_handler,name='SIGHUP'),
    )
event_loop.add_signal_handler(
    signal.SIGUSR1,
    functools.partial(signal_handler,name='SIGUSR1'),
    )
event_loop.add_signal_handler(
    signal.SIGINT,
    functools.partial(signal_handler,name='SIGINT'),
    )

# 这个示例程序使用了一个协程通过os.kill()向自身发送信号。发送各个信号之后,协程
# 交出控制,从而允许这个处理器运行。在一个真是的应用中,可能有更多位置上的应用
# 代码会把控制交回给事件循环,所以不需要(像这个例子中一样)人为地交出控制。
async def send_signals():
    pid = os.getpid()
    print('starting send_signals for {}'.format(pid))

    for name in ['SIGHUP','SIGHUP','SIGUSR1','SIGINT']:
        print('sending {}'.format(name))
        os.kill(pid,getattr(signal,name))
        # Yield control to allow the signal handler to run,
        # since the signal does not interrupt the program
        # flow otherwise.
        print('yielding control')
        await asyncio.sleep(0.01)
    return
# 主程序运行send_signals(),直到已经发出所有信号。
try:
    event_loop.run_until_complete(send_signals())
finally:
    event_loop.close()

输出显示了发送一个信号后send_signals()交出控制时如何调用处理器。
在这里插入图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值