由于在一个线程中接入了一个第三方服务,这个远程服务并不是很重要,远程调用线路和请求总有失败的可能。
因此,就想把这个函数放在 Try 中去运行:
try:
do_something()
except:
pass
由于每次 do_something() 会阻塞当前线程,所以想限制个最长执行时间,超时直接 pass 。
用 eventlet 有点偏重,有没有什么比较简单的实现优雅的实现方法?
1
imn1 2020-10-03 13:58:23 +08:00
远程模块一般都有 timeout 异常的
|
2
Mitt 2020-10-03 13:58:53 +08:00 via iPhone
开线程超时然后强制终止?
|
3
kangsheng9527 2020-10-03 13:59:27 +08:00
python 不知道,go 可以使用 context 包去处理。。。
|
4
JeffGe 2020-10-03 14:01:49 +08:00 via Android
新建进程超时就 kill 可行吗
|
5
dbow 2020-10-03 14:08:41 +08:00
这种得用协程要搞, python3 里边有 async, await, 前提是你使用的库支持这么操作.
|
6
infun 2020-10-03 14:09:50 +08:00
试试 retrying 库
|
7
ClericPy 2020-10-03 14:30:37 +08:00
线程差就差在没法外部强制停止, 所以这种场景我都是协程跑的, 外部超时直接发送 cancel 指令
至于远程调用相关的, 一般会有超时控制吧, 具体看你 do 了什么 thing 了 |
8
MoYi123 2020-10-03 14:37:27 +08:00 2
@contextmanager
def timeout_signal(second): ____signal.signal(signal.SIGALRM, raise_timeout) ____signal.alarm(second) ____try: ________yield ____finally: ________signal.signal(signal.SIGALRM, signal.SIG_IGN) def raise_timeout(_signum, _frame): ____raise TimeoutError def timeout(second): ____def _timeout(fun): ________@wraps(fun) ________def _fun(*args, **kwargs): ____________with timeout_signal(second): ________________return fun(*args, **kwargs) ________return _fun ____return _timeout @timeout(1) def f(): ____pass 我平时的用脚本里是这样写的,性能好坏不确定。 |
9
MiracleKagari 2020-10-03 18:24:06 +08:00 via Android
rxpy 应该有
|
10
MiracleKagari 2020-10-03 20:12:02 +08:00 via Android
@MiracleKagari 创建一个响应式对象,然后找一个合适的操作符,然后...
|
11
tkmiles 2020-10-03 20:49:07 +08:00
使用 future 呀
一个线程结束之后更新 future 另外一个线程在 future 上等待, future 上可以加 timeout 的 然后另外一个线程在 timeout 之后直接终止子线程 python 终止子线程有点限制, 只能发送线程异步异常去终止 python 代码执行, 如果你卡在 C 级别的代码, 那只能等待 回调回 python 代码的时候, 异步异常才能终止线程 如果你想终止线程更严格一点, 比如终止 C 代码, 那么只能求助于系统中断了 |
12
itskingname 2020-10-03 21:11:17 +08:00
如果是 macOS 和 Linux,我写过一篇文章来说明: https://mp.weixin.qq.com/s/PUcHuJMG5Mk2tWWzYeq2wQ
|
13
l4ever 2020-10-04 02:33:47 +08:00 via iPhone
import multiprocessing as mp
def pool_funcs(func, args=(), kwds=None, timeout=1, default=None): """ 线程超时 @param func: @param args: @param kwds: @param timeout: @param default: @return: """ pool = mp.Pool(processes=1) result = pool.apply_async(func, args=args, kwds=kwds) try: val = result.get(timeout=timeout) except mp.TimeoutError: pool.terminate() return default else: pool.close() pool.join() return val |
14
namelosw 2020-10-04 03:43:06 +08:00 1
这个和停机问题相关,如果语言没有提供特殊的机制的话一般要靠子进程+监护的形式,因为停机是没法本地恢复的。像大量应用这种模式的 Erlang,也是尽量通过把进程做得超级轻量化,然后用同样的方式实现的。
还有一些形式就是自己写一个简单的类似解释器的东西,你重新发明并嵌入一个语言,这个语言的解释归你管,就可以在每个求值周期都检查一次 timeout 。类似的例子比较像 React fiber —— 不过 fiber 只能管 React 渲染,而不能管 JavaScript 执行,也就是说这种 timeout 就 kill 掉的机制只能对 React 自己的 DSL ( JSX 以及 Element 的 Rendering )成立,而对 JavaScript 没有普适性,除非重新实现一遍 JavaScript,或者启另外一个 JavaScript 进程。 |