Python 避免在写入命名管道时挂起,因为命名管道会消失并返回

Python 避免在写入命名管道时挂起,因为命名管道会消失并返回,python,Python,我有一个程序,它将信息转储到命名管道中,如下所示: cmd=open(destination,'w') cmd.write(data) cmd.close() 在我的程序写入管道(目的地)时管道消失之前,这一切都很正常。问题是它一直挂在写入部分(?) 我原以为会有例外,但事实并非如此。 我怎样才能避免这种情况 谢谢 Jay我认为信号模块可以帮助您。检查此示例: (该示例解决了一个可能未完成的open()调用,但可以对其进行简单的修改,以便对cmd.write()调用执行相同的操作。)如果从管

我有一个程序,它将信息转储到命名管道中,如下所示:

cmd=open(destination,'w')
cmd.write(data)
cmd.close()
在我的程序写入管道(目的地)时管道消失之前,这一切都很正常。问题是它一直挂在写入部分(?) 我原以为会有例外,但事实并非如此。 我怎样才能避免这种情况

谢谢


Jay

我认为信号模块可以帮助您。检查此示例:


(该示例解决了一个可能未完成的
open()
调用,但可以对其进行简单的修改,以便对
cmd.write()
调用执行相同的操作。)

如果从管道读取的进程的读取速度不如您的写入速度快,则脚本将在尝试写入管道时阻塞。来自维基百科:

如果队列缓冲区已满,则 发送程序被挂起(阻止) 直到接收程序有一个 有机会阅读一些数据并腾出空间 在Linux中,缓冲区的大小 缓冲区为65536字节。”

幸运的是,您有几个选择:

  • 信号模块将允许您设置报警以中断写呼叫。在规定的时间量之后,一个SIGALRM信号将被发送到您的进程,如果该信号的处理程序引发异常,它将中断您的写入

  • 使用线程,您可以生成一个新线程来处理写操作,如果它阻塞太长时间,就会杀死它

  • 您还可以使用fnctl模块使管道非阻塞(这意味着调用不会等待,如果管道已满,它将立即失败):

  • 最后,在尝试写入之前,可以使用select模块检查管道是否已准备好写入,但要小心,check write操作不是幂等的(例如,管道可能在check和write之间填满)


我们在谈论什么操作系统?那就是linux。知道这一点确实很重要。我确实想到了这一点,这将是一条出路,但目前这不是一个选项,因为写入发生在阻塞线程中,显然不可能在线程中使用信号,而只能在main()中使用信号。。。对于我来说,实现这一点需要进行一些重新设计。在主线程中接收信号,然后调用
thread.exit()
?从我读到的内容来看,应该避免信令和线程。无论如何,我已经决定做另一个线程来处理决定写的线程中的实际写操作。我相信还有其他的方法,但它是有效的。我会研究第三种选择,如果不可行,我认为第二种选择会符合我的目的。信号不是选项,因为这种写入已经在线程中发生。第四个选项听起来很棘手,因为我可能不是唯一一个写入该管道的进程。
select
很容易使用,但我相信,在这种情况下,它可能并不完全足够,因为管道可能会在
select()
调用和
write()
调用之间消失。是的,佩德罗,这就是问题所在。操作系统可以在检查后立即切换上下文,填充管道,然后切换回您的写入(现在将失败)。Ops。看来你在答复中已经提到了这一点。我想我不应该在睡觉前发帖子。对不起。:)我选择在一个专用线程中进行写入,并在线程对象上使用一个带有超时的连接,看起来它正在完成这项工作。但现在的问题是,如何杀死线程?由于终止线程似乎不是好的做法。。。但就我而言,这很清楚。我使用“del object”来终止线程。。。我希望这足够了。