Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/python-3.x/16.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/unix/3.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Python 3.x 如何取消阻止已删除命名管道上的线程阻塞?_Python 3.x_Unix_Pipe_Posix_Named Pipes - Fatal编程技术网

Python 3.x 如何取消阻止已删除命名管道上的线程阻塞?

Python 3.x 如何取消阻止已删除命名管道上的线程阻塞?,python-3.x,unix,pipe,posix,named-pipes,Python 3.x,Unix,Pipe,Posix,Named Pipes,我有一个Python程序,它将命名管道用于各种用途。 每个管道都是从不同的线程管理的,因此不会阻塞主线程 假设我有一个线程在调用open('in','rb')时阻塞,其中in是命名管道的相对路径。 如果我想关闭我的程序,我会使用类似这样的方法来解除我的线程与其他线程的连接: with suppress(OSError): fd = os.open('in', O_WRONLY | O_NONBLOCK) os.close(fd) 这只是在写入模式下打开管道,以便open上的线程

我有一个Python程序,它将命名管道用于各种用途。 每个管道都是从不同的线程管理的,因此不会阻塞主线程

假设我有一个线程在调用
open('in','rb')
时阻塞,其中
in
是命名管道的相对路径。 如果我想关闭我的程序,我会使用类似这样的方法来解除我的线程与其他线程的连接:

with suppress(OSError):
    fd = os.open('in', O_WRONLY | O_NONBLOCK)
    os.close(fd)
这只是在写入模式下打开管道,以便
open
上的线程阻塞可以继续,然后关闭它。我使用
O_NONBLOCK
避免在另一个线程已经终止时阻塞(并忽略潜在的
OSError

在有人决定删除中的命名管道
,而我的线程在
open
上阻塞之前,这一切都很正常。 在这种情况下,我不能使用“尝试在非阻塞模式下打开管道并关闭它”方法,因为管道在文件系统上不再可见(而非阻塞打开只会创建一个全新的管道)

除了终止线程之外,这个问题的正确解决方案是什么?
请注意,我无法阻止其他进程删除管道,权限也无济于事(删除进程可以以root身份运行)。

我已通过使用
os.open('in',O|RDONLY | O| NONBLOCK)
解决了我的问题,即使管道的另一端没有写入程序,它也会生成一个文件描述符

一旦我有了一个用于读取的有效文件描述符,我就能够将其提供给
select()
系统调用,直到有东西要读取为止

为了解决“如果有人在我阻塞时从文件系统中删除管道会怎么样”的问题,我使用了
pipe()
syscall来获取一个未命名的管道(Python版本只为管道的两端生成两个文件描述符)


我也将此未命名管道的读取描述符馈送到
select()
调用,因此每当我希望停止程序时,我只需通过写入未命名管道的写入描述符来解除阻止
select()
,而不管命名管道出现了什么问题。

我已使用
os.open解决了我的问题('in',O_RDONLY | O_NONBLOCK)
,即使管道的另一端没有写入程序,也会生成文件描述符

一旦我有了一个用于读取的有效文件描述符,我就能够将其提供给
select()
系统调用,直到有东西要读取为止

为了解决“如果有人在我阻塞时从文件系统中删除管道会怎么样”的问题,我使用了
pipe()
syscall来获取一个未命名的管道(Python版本只为管道的两端生成两个文件描述符)


我还将此未命名管道的读取描述符馈送给
select()
调用,因此每当我希望停止程序时,我只需取消阻止
select()
通过写入未命名管道的写入描述符,而不管命名管道出了什么问题。

最坏的情况是,我可以使用非阻塞打开来轮询管道,而不是在打开管道时显式阻塞,但我发现阻塞方法更优雅,因为轮询需要浪费CPU周期并引入时间因素。您的问题em听起来像是XY(为什么会有人首先使用命名管道?)。但是如果设置了信号处理程序,发送信号将中断blocking open()系统调用,允许程序在处理EINTR错误后继续。因此,您可以发送信号,而不是使用“打开/关闭”技巧。@mosvy我必须使用命名管道(说来话长)。这在Python(3.7)中可以实现吗?文档中说:“Python信号处理程序总是在主Python线程中执行,即使信号是在另一个线程中接收的。这意味着信号不能用作线程间通信的手段。”信号处理程序不必做任何事情;只需中断open()syscall。查看“答案”(我不是python程序员,所以这可能不是最好的方法)。另一个想法是使用
O_RDWR
(它不会阻塞)打开命名管道——但在这种情况下,您无法通过EOF确定编写器何时关闭了管道的末端。似乎没有办法打开命名管道)在python中获取真正的线程id(为向特定线程发送信号所必需的)和b)在python3中处理EINTR——所有系统调用都将由解释器手动重新启动(但在python2中仍然可以)。因此,唯一的解决方法是以读写模式打开命名管道(这在所有现代系统上都支持)。最坏的情况是,我可以使用非阻塞打开轮询管道,而不是在打开管道时显式阻塞,但我发现阻塞方法更优雅,因为轮询需要浪费CPU周期并引入了一个时间因素。您的问题听起来像是XY问题(归根结底是为什么会有人首先使用命名管道?)。但是如果您设置了一个信号处理程序,发送该信号将中断blocking open()系统调用,从而允许您的程序在处理EINTR错误后继续。所以你可以发送一个信号,而不是开/关的把戏。@mosvy我必须使用命名管道(长话短说)。在Python(3.7)中可以这样做吗?文档说:“Python信号处理程序总是在主Python线程中执行,即使信号是在另一个线程中接收到的。这意味着信号不能用作线程间通信的手段。”信号处理程序不必做任何事情;只是为了中断open()系统调用。请参阅“答案”(我不是python程序员,因此这可能不是最好的方法)。另一个想法是使用
O_RDWR
(不会阻塞)打开命名管道——但在这种情况下,您无法通过EOF确定编写器何时关闭了管道的末端。似乎无法a)在python中获取真实的线程id(向特定线程发送信号所必需的)和b)ha