线上问题:FastAPI和trafilatura出现ValueError: signal only works in main thread of the main interpreter

1 场景复现

相关工具及版本:
fastapi==0.95.0
trafilatura==1.5.0
python==3.10
使用FastAPI开发获取URL内容的接口:
抛出的异常如下:

File “/app/src/utils/file_process_util.py”, line 66, in request_data_from_url
text = trafilatura.extract(source_data)
File “/usr/local/lib/python3.10/site-packages/trafilatura/core.py”, line 1050, in extract
signal(SIGALRM, timeout_handler)
File “/usr/local/lib/python3.10/signal.py”, line 56, in signal
handler = _signal.signal(_enum_to_int(signalnum), _enum_to_int(handler))
ValueError: signal only works in main thread of the main interpreter

2 代码

import  trafilatura

def request_data_from_url
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
### 回答1: 这个错误是因为在非主线程中使用了信号(signal)。在Python中,信号(signal)只能在主线程中使用,如果在其他线程中使用,就会出现这个错误。要解决这个问题,可以将信号处理程序放在主线程中,或者使用线程安全的信号处理方式。 ### 回答2: valueerror: signal only works in main thread(信号仅在主线程中工作)是一个Python编程中常见的错误信息,通常出现在多线程编程中。 多线程编程是指创建多个线程,在不同的线程中同时运行不同的代码。这种编程方式可以提高程序的性能和效率,但也带来了线程安全问题。在多线程编程中,如果子线程想要修改主线程的某些属性或执行某些操作,就需要使用信号(signal)来通知主线程。 在Python中,信号(signal)是一种线程间通信的方式。主线程可以在接收到信号后,执行与信号绑定的回调函数,实现对子线程的控制。但是,Python的信号(signal)只能在主线程中接收和处理,如果在子线程中创建信号(signal),就会出现valueerror: signal only works in main thread(信号只在主线程中有效)的错误信息。 原因是Python的信号(signal)是基于操作系统提供的信号机制实现的,而不同的操作系统实现信号机制的方式不同。为了确保线程安全,Python规定只有主线程才能接收和处理信号(signal)。因此,在多线程编程中,在子线程中创建和处理信号(signal)是不可行的。 要解决这个错误,可以通过在主线程中创建信号(signal),并将信号与子线程绑定,让子线程触发信号(signal),从而实现主线程对子线程的控制。另外,还可以使用Python的Queue模块来实现线程间的通信,避免在子线程中创建信号(signal)。 ### 回答3: 这个错误通常会在Python多线程编程中出现。简单地说,该错误是由于尝试在非主线程中使用signal模块引起的。signal模块在Python中用于处理UNIX信号,它允许我们在程序接收到UNIX信号时执行特定的操作。但是,signal模块只能在主线程中使用,这意味着我们必须将信号处理程序放在主线程中,否则就会遇到“valueerror: signal only works in main thread”的错误。 为了解决这个问题,我们需要将signal模块中的信号处理程序封装到一个函数中,然后在主线程中调用这个函数。例如,我们可以使用Python的threading模块来创建多个线程,但必须将信号处理程序放在主线程中。下面是一个示例代码: ``` import signal import threading def signal_handler(sig, frame): print('Signal received: {}'.format(sig)) def main(): signal.signal(signal.SIGINT, signal_handler) thread = threading.Thread(target=worker) thread.start() def worker(): while True: pass if __name__ == '__main__': main() ``` 在这个例子中,我们在主线程中注册了SIGINT信号的处理程序,该程序在程序接收到SIGINT信号时打印一条消息。我们还创建了一个worker线程并启动它。由于SIGINT信号处理程序在主线程中注册,因此它仅在程序接收到信号时被调用,而不是在worker线程中无限循环期间被调用。 总之,我们需要注意的是,signal模块只能在主线程中使用,不能在其他线程中使用。因此,在多线程编程中,我们应该将信号处理程序放在主线程中,并在必要时使用线程间通信机制进行通信。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

天然玩家

坚持才能做到极致

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值