避免在写入消失后又出现的命名管道时发生挂起

3 投票
2 回答
4591 浏览
提问于 2025-04-16 11:11

我有一个程序,它会把信息写入一个叫做命名管道的东西,像这样:

cmd=open(destination,'w')
cmd.write(data)
cmd.close()

这个方法运行得还不错,直到在我程序写入的时候,这个管道(目的地)突然消失了。问题是,程序在写入的部分会一直卡住(?)我原本以为会出现一些错误提示,但实际上并没有。请问我该怎么避免这种情况呢?

谢谢,

Jay

2 个回答

0

我觉得信号模块可以帮到你。看看这个例子:

http://docs.python.org/library/signal.html#example

(这个例子解决了一个可能不会结束的 open() 调用,但可以很简单地修改成对你的 cmd.write() 调用做同样的事情。)

4

如果从管道中读取数据的进程速度跟不上你写入的速度,当你的脚本尝试写入管道时,就会出现阻塞的情况。根据维基百科的文章

“如果队列缓冲区满了,发送程序会被暂停(阻塞),直到接收程序有机会读取一些数据并在缓冲区中腾出空间。在Linux中,缓冲区的大小是65536字节。”

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

  • 可以使用信号模块来设置一个警报,以便在写入调用时中断。经过设定的时间后,会向你的进程发送一个SIGALRM信号,如果你对这个信号的处理程序抛出异常,就会中断写入。

  • 通过线程,你可以创建一个新的线程来处理写入,如果这个线程阻塞太久,就可以把它杀掉。

  • 你还可以使用fnctl模块将管道设置为非阻塞(这意味着调用不会等待,如果管道满了,它会立即失败):在Python中对subprocess.PIPE进行非阻塞读取

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

撰写回答