python执行时间长被kill_python 超时任务kill

编程过程中遇到代码执行超时问题。场景是在主进程中启动多个子进程并行执行,假设平时一个进程10分钟能执行完毕,但在一些极端情况下执行一个小时也没结束,此时需要杀掉子进程,返回任务执行失败。

用python的进程池执行操作时没法设置超时时间,只能从进程内部想办法。

思路一:

用timer定时,当执行时间超时时让进程终止:

def cancel_cur_computer():

#通过抛出异常,来终止当前执行节点

logging.warning("%s timeout killed" % str(os.getpid()))

os.kill(os.getpid(), signal.SIGKILL)

logging.warning("%s timeout killed" % str(os.getpid()))

def run():

timer = threading.Timer(3, cancel_cur_computer)

print("bbb")

timer.start()

time.sleep(20)

def test_timer():

pool = Pool(3)

try:

for i in range(0, 3):

#run()

pool.apply_async(run)

except Exception as e:

logging.exception(e)

pool.close()

pool.join()

test_timer()

当不用进程池时,即打开run(),注释pool.apply_async(run),执行没有问题,定时器可以杀死进程。

当使用进程池,即注释run(),打开pool.apply_async(run),可以打印出logging.warning("%s timeout killed" % str(os.getpid())),但进程没有被杀死,反而一直卡死在os.kill(os.getpid(), signal.SIGKILL)处,我猜可能与进程池有关系。杀掉进程池中的进程也不合理。

思路二

用single的闹钟来解决这个问题

def handler(signum, frame):

raise Exception("timeout...")

def run():

try:

signal.signal(signal.SIGALRM, handler)

signal.alarm(3) # 设置超时时间为3s

time.sleep(40) # 模拟长时间执行任务

except Exception as e:

logging.exception(e)

finally:

signal.alarm(0) # 取消闹钟

print("aaaaa")

def test_timer():

pool = Pool(3)

try:

for i in range(0, 3):

pool.apply_async(run)

except Exception as e:

logging.exception(e)

pool.close()

pool.join()

test_timer()

解决问题。

`channels.layers.InMemoryChannelLayer` 是 Django Channels 中的一种内存级别的通信层,用于处理实时消息传递。当发送的消息时间未被接收者消费(即超时),InMemoryChannelLayer 会默认关闭(kill)那个通道,这可能是为了避免资源泄露。 如果你遇到因为超时而被 kill 的情况,有几种常见的解决方案: 1. **设置合理的超时时间**:通过配置 `asynchronous_timeout` 或 `connection_timeout` 参数,可以调整消费者接收到消息后的响应时间,确保它们能在规定时间内完成处理。 ```python from channels.layers import get_channel_layer channel_layer = get_channel_layer({ 'default': { 'BACKEND': 'channels.layers.InMemoryChannelLayer', 'TIMEOUT': 60, # 设置默认超时时间为60秒, } }) ``` 2. **优化消费者处理逻辑**:检消费者的处理函数是否有阻塞操作,如果有,需要保证其尽快返回,或者使用异步任务来处理耗时部分。 3. **心跳机制**:为连接添加心跳检测,定期向服务器发送确认信息,防止因时间无活动而导致超时。Django Channels 提供了第三方库如 `django-heartbeat` 来实现这个功能。 4. **异常处理**:在消费者内部捕获 `ConsumerTimeoutError`,并在捕获到时手动关闭通道,避免通道被自动 kill。 ```python class MyConsumer(AsyncWebConsumer): async def receive(self, text_data=None, bytes_data=None, **kwargs): try: await self.do_something() except ConsumerTimeoutError: await self.close() ```
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值