gpt4 book ai didi

python - 在 Python 中处理阻塞函数调用

转载 作者:太空狗 更新时间:2023-10-30 01:47:16 26 4
gpt4 key购买 nike

我正在使用 Gnuradio framework .我处理我生成的流程图以发送/接收信号。这些流程图会初始化并启动,但它们不会将控制流返回给我的应用程序:

我导入了time

while time.time() < endtime:
# invoke GRC flowgraph for 1st sequence
if not seq1_sent:
tb = send_seq_2.top_block()
tb.Run(True)
seq1_sent = True
if time.time() < endtime:
break

# invoke GRC flowgraph for 2nd sequence
if not seq2_sent:
tb = send_seq_2.top_block()
tb.Run(True)
seq2_sent = True
if time.time() < endtime:
break

问题是:只有第一个 if 语句调用流程图(与硬件交互)。我被困在这个。我可以使用线程,但我没有经验如何在 Python 中使线程超时。我怀疑这是可能的,因为杀死线程似乎不在 API 中。这个脚本只需要在 Linux 上工作...

如何使用 Python 正确处理阻塞函数 - 而不会终止整个程序。这个问题的另一个更具体的例子是:

import signal, os

def handler(signum, frame):
# print 'Signal handler called with signal', signum
#raise IOError("Couldn't open device!")
import time
print "wait"
time.sleep(3)


def foo():
# Set the signal handler and a 5-second alarm
signal.signal(signal.SIGALRM, handler)
signal.alarm(3)

# This open() may hang indefinitely
fd = os.open('/dev/ttys0', os.O_RDWR)
signal.alarm(0) # Disable the alarm


foo()
print "hallo"

我如何仍然得到 print "hallo"。 ;)

谢谢,马吕斯

最佳答案

首先 - 应不惜一切代价避免使用信号:

1) 可能会导致死锁。 SIGALRM 可能会在阻塞系统调用之前到达进程(想象一下系统中的超高负载!)并且系统调用不会被中断。死锁。

2) 使用信号可能会产生一些令人讨厌的非本地后果。例如,其他线程中的系统调用可能会被中断,这通常不是您想要的。通常,系统调用会在收到(不是致命的)信号时重新启动。当您设置信号处理程序时,它会自动关闭整个进程或线程组的这种行为。检查“man siginterrupt”。

相信我 - 我之前遇到过两个问题,它们一点都不好玩。

在某些情况下,可以明确避免阻塞——我强烈建议使用 select() 和它的 friend (检查 Python 中的 select 模块)来处理阻塞的写入和读取。不过,这不会解决阻塞 open() 调用的问题。

为此,我测试了这个解决方案,它适用于命名管道。它以非阻塞方式打开,然后将其关闭并使用 select() 调用最终超时(如果没有可用内容)。

import sys, os, select, fcntl

f = os.open(sys.argv[1], os.O_RDONLY | os.O_NONBLOCK)

flags = fcntl.fcntl(f, fcntl.F_GETFL, 0)
fcntl.fcntl(f, fcntl.F_SETFL, flags & ~os.O_NONBLOCK)

r, w, e = select.select([f], [], [], 2.0)

if r == [f]:
print 'ready'
print os.read(f, 100)
else:
print 'unready'

os.close(f)

测试这个:

mkfifo /tmp/fifo
python <code_above.py> /tmp/fifo (1st terminal)
echo abcd > /tmp/fifo (2nd terminal)

通过一些额外的努力,select() 调用可以用作整个程序的主循环,聚合所有事件 - 您可以使用 libev 或 libevent,或围绕它们的一些 Python 包装器。

当你不能明确地强制非阻塞行为时,假设你只是使用一个外部库,那么它会变得更加困难。线程可能可以,但显然它不是最先进的解决方案,通常是错误的。

恐怕一般情况下您无法以稳健的方式解决此问题 - 这实际上取决于您阻止的内容。

关于python - 在 Python 中处理阻塞函数调用,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/4051261/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com