最近处理一个线程中的函数超时问题.

函数里面有一个地方可能会卡死,我们需要去判断这个是不是卡死了,并做出相应的应对方案.

最开始想的是在函数上增加一个装饰器,使其在超时时抛出异常,然后在其他地方捕获这个异常,并处理.

查询了一些前人的方案,写出的结果有两种.

方案一:使用threading的timer定时器,代码如下:

from threading import timer

def time_limit(interval):
def wraps(func):
def time_out():
raise RuntimeError() def deco(*args, **kwargs):
timer = Timer(interval, time_out)
timer.start()
res = func(*args, **kwargs)
timer.cancel()
return res
return deco
return wraps

这个程序,在很多网页上看到了,使用方式,在需要监控的函数上写@time_limit(5),即可定时5秒报错.经过测试,觉得没什么用.

粗略看来,运行一下确实在程序超过interval规定的时间后抛出了RuntimeError.但是由于timer是另开的一个线程,所以这个异常别人获取不到,只有在本线程里处理才有用.

而且卡死的函数也不会停下来.

这种处理方式仅仅适用于一些函数与定时并不密切的时候,只是在函数超时时需要做一些动作的情况.

方案二:使用signal信号量机制,代码如下:


import signal
def time_limit(interval):
def wraps(func):
def handler():
raise RuntimeError()
def deco(*args, **kwargs):
signal.signal(signal.SIGALRM, handler)
signal.alarm(interval)
res = func(*args, **kwargs)
signal.alarm(0)
return res
return deco
return wraps

可以看出来,代码基本一样.但是原理大不相同.运行的结果也不一样,这段代码装饰需要定时的函数,在函数运行超时之后会抛出异常,停止程序.

一般情况下,这个装饰器就够用了.与之相同的方案,还有python的timeout模块,

可以直接pip install timeout,然后from timeout import timeout,在需要的函数前@timeout(n)即可.

这个方案已经很不错了,然而在实际应用中,由于是多线程,而signal不能在子线程中使用,所以否认了这个方案.

比较简单的装饰器想法否定掉了,就想了一些其他的办法.

1.定时检测线程是否alive----------卡死的线程只是不动,还是alive的

2.由于函数是生产者,可以通过计算时间,一定时间没有新的产出,则判定这个函数卡死,然后杀掉这个线程,重开一个----------python不支持杀掉线程

3.在线程里面增加标志位,检测标志位改变则退出循环----------天真的想法

4.改变线程为可接受stop的线程----------卡住不动收不到信号的,除非是进程

提出一些方案发现可行性都很低,最后也没有完全解决卡死的问题.

虽然这一个线程卡死并不会影响整个程序往下走,但是不生产,又占据资源不合理.

觉得否认了这些方案以后,最干脆的办法是检测到这个卡死之后,手动或自动杀掉其父进程.重启服务.

还有较不优雅的办法,由于卡死的情况不会很多,就记录下来,然后新开一个线程替代它的工作,直到记录队列满了,给一个信号要求重启服务.

重启服务影响较大,不建议随便重启.

总的说下来,还是没有较好的方案解决线程卡死的问题,毕竟函数卡死了就是卡死了,没法走下去,而且在线程里面又没法外界停下来.

先做一个记录吧!在继续学习的路上,希望有好的办法.

python函数超时情况应对总结的更多相关文章

  1. python函数超时,用装饰器解决 func_timeout

    https://zhuanlan.zhihu.com/p/39743129 https://www.jianshu.com/p/a7fc98c7af4d https://ixyzero.com/blo ...

  2. python 函数之day3

    一 函数的语法及特性 什么是函数? 定义:函数是一个功能通过一组语句的集合,由名字(函数名)将其封装起来的代码块,要想执行这个函数,只要调用其函数名即可. 特性: 减少重复代码 使程序变的可扩展 使程 ...

  3. Python函数参数默认值的陷阱和原理深究"

    本文将介绍使用mutable对象作为Python函数参数默认值潜在的危害,以及其实现原理和设计目的 本博客已经迁移至: http://cenalulu.github.io/ 本篇博文已经迁移,阅读全文 ...

  4. Python开发【第四章】:Python函数剖析

    一.Python函数剖析 1.函数的调用顺序 #!/usr/bin/env python # -*- coding:utf-8 -*- #-Author-Lian #函数错误的调用方式 def fun ...

  5. Python入门笔记(20):Python函数(3):关于lambda

    一.lambda函数 1.lambda函数基础: lambda函数也叫匿名函数,即,函数没有具体的名称,而用def创建的方法是有名称的.如下: """命名的foo函数&q ...

  6. Python入门笔记(18):Python函数(1):基础部分

    一.什么是函数.方法.过程 推荐阅读:http://www.cnblogs.com/snandy/archive/2011/08/29/2153871.html 一般程序设计语言包含两种基本的抽象:过 ...

  7. Day03 - Python 函数

    1. 函数简介 函数是组织好的,可重复使用的,用来实现单一或相关联功能的代码段. 函数能提高应用的模块性,和代码的重复利用率.Python提供了许多内建函数,比如print():也可以自己创建函数,这 ...

  8. python函数的返回值 讲解

    我们一起来聊聊python函数返回值的特殊情况,之前我也碰到过类似方面的问题,到后来查阅了一些资料后,发现原来是这样. 首先,写函数的时候,一定要写函数的文档,这样方便我们识别函数是做什么的.我记得很 ...

  9. Python 函数之路

    ---恢复内容开始--- python函数的定义 def add(): a = 1 b = 2 c == a + b print(c) 函数就是把一段实现某一个功能的代放进一个封装的方法名里,这个方法 ...

随机推荐

  1. Locality preserving hashing for fast image search: theory and applications

    Is there any Java library that provides an implementation (or several) of a Locality Preserving Hash ...

  2. 编写高质量代码改善C#程序的157个建议——建议147:重构多个相关属性为一个类

    建议147:重构多个相关属性为一个类 若存在多个相关属性,就应该考虑是否将其重构为一个类.查看如下类: class Person { public string Address { get; set; ...

  3. (自己转)比较ArrayList、LinkedList、Vector

    1. List概述 List,就如图名字所示一样,是元素的有序列表.当我们讨论List时,将其与Set作对比是一个很好的办法,Set集合中的元素是无序且唯一的.下图是Collection的类继承图,从 ...

  4. Java知多少虚拟机(JVM)以及跨平台原理

    相信大家已经了解到Java具有跨平台的特性,可以“一次编译,到处运行”,在Windows下编写的程序,无需任何修改就可以在Linux下运行,这是C和C++很难做到的. 那么,跨平台是怎样实现的呢?这就 ...

  5. 常用SQL语句集锦

    MySQL适用 1.如图所示,根据Coord字段内容填充X/Y字段,并调整Coord字段格式(Coord字段原为[Latitude,Longitude]格式,需要将其调整为[Longitude,Lat ...

  6. Oracle数据表转换为Shapefile(一)

    严格来说,文章标题中的“转换”并不完全合适.本文的主要内容是基于Oracle数据表的数据来生产出Shapefile文件.进行该工作的一个前提条件是:Oracle数据表中包含坐标数值字段,一般来说就是x ...

  7. Re:从零开始的Spring Security Oauth2(三)

    上一篇文章中我们介绍了获取token的流程,这一篇重点分析一下,携带token访问受限资源时,内部的工作流程. @EnableResourceServer与@EnableAuthorizationSe ...

  8. Spring Boot专题背景简介

    鄙人13年毕业,不曾在圈子里写过总结,因此文笔颇不自信. 但人生永远没有太晚的开始,现在开始做些笔记,借此巩固下学到的新知识. 一些题外话: 前段时间,做个小项目,由于某些原因,使用Java来写(之前 ...

  9. Windows 2012 R2版本下部署IIS网站

    Windows 2012 R2是一个比较稳定的服务器版本,本文分享一篇在Windows 2012 R2版本下搭建IIS项目的操作流程. 1. 安装IIS Web服务器 打开远程桌面->控制面板- ...

  10. windows部署PHP开发的cms系统

    近日,由于公司服务器中了病毒,导致公司官网上的源代码文件被篡改,而且也被谷歌标记为危险网站,而且病毒很顽固,难已删除,迫不得已只好将服务器系统重做,数据全部格式掉. 数据全部都没有,网站当然要重新发布 ...