初始化

记录技术与生活

Python跨平台函数执行时间限制

项目中用到的一个小功能,但是在网上没有找到相关的任何比较好的想法/实现。

自己想到一种Python跨平台实现函数执行时间限制的思路。

网上的方法比较多的是利用信号量 signal 设置一个定时器,超时之后执行回调函数,引发 TimeoutError,退出执行。

这种方法易于实现,并且占用资源少,只需要设置一个 signal.alarm 的闹钟即可。

但是缺点也显而易见:在 Windows平台 并不能够使用。

分析 signal 的这种方式,我有了一种灵感:让触发退出的回调函数与任务函数 “抢占执行” —— 谁先执行完,就返回谁的值:在计时线程返回之后,不管任务子线程的执行结果,直接返回错误/返回指定值。

threading 库中有一个 Timer 函数,我们用它来计时;在整个过程中,需要同步线程内部的值到父线程/主进程中 —— 最好的选择个人认为还是队列。这里我们不单单将闭包中的队列变量用来同步 return 的值,还可以利用队列一个很好的特性 —— 锁,在任务线程和计时线程均开始运行之后,可以用队列的 get 锁把父线程/主进程阻塞掉,这样既能保证很低的系统占用,又可以实现回收线程返回值的目标(但我这里单独给了一个锁变量控制),一举两得。

下面贴代码:

如果不想让超时之后引发 TimeoutError,请给装饰器传入 default参数,作为超时之后的默认返回值。

另外需要注意的一点时:任务函数并不会随着装饰器函数的退出而结束,因为在这里父线程是主进程,虽然设置了 Daemon ,但是装饰起函数退出后,主进程仍在执行,便不会退出任务线程(如果一定要退出任务线程,请考虑将整个过程单独出来成为一个线程,但是这样回更多的占用资源,并且需要再次同步父线程和主进程之间的返回值,比较麻烦。)

这样就可以实现跨平台的函数执行时间限制。

点赞

发表评论

电子邮件地址不会被公开。 必填项已用*标注

This site uses Akismet to reduce spam. Learn how your comment data is processed.