C fifo:取消阻止挂起的打开呼叫

C fifo:取消阻止挂起的打开呼叫,c,macos,posix,named-pipes,mkfifo,C,Macos,Posix,Named Pipes,Mkfifo,我为IPC使用一个名为pipe的FIFO。现在处理一个电话 mkfifospath 开放路径 自然打开将阻止,直到文件被进程B写入。现在我需要一种使FIFO无效的方法。因此,我呼吁 取消链接路径 现在我期望任何阻塞打开调用都会返回,但它们不会返回,并且我的进程会无限期挂起 当FIFO断开链接时,如何解除对打开呼叫的阻止? 我必须求助于O_Non Block吗 PS:我尝试了建议的写入/取消链接/关闭方法,但没有效果。打开的调用立即阻塞 void invalidate() { int fd

我为IPC使用一个名为pipe的FIFO。现在处理一个电话

mkfifospath 开放路径 自然打开将阻止,直到文件被进程B写入。现在我需要一种使FIFO无效的方法。因此,我呼吁

取消链接路径 现在我期望任何阻塞打开调用都会返回,但它们不会返回,并且我的进程会无限期挂起

当FIFO断开链接时,如何解除对打开呼叫的阻止? 我必须求助于O_Non Block吗

PS:我尝试了建议的写入/取消链接/关闭方法,但没有效果。打开的调用立即阻塞

void invalidate() {
    int fd = open(path, O_WRONLY)
    unlink(path)
    close(fd)
}
我认为问题是

在读取和写入数据之前,必须在两端打开FIFO 可以通过。通常,打开FIFO块直到另一端 也开放了


但是,invalidate应在不知道FIFO当前是否打开进行读取的情况下工作。

打开FIFO进行写入,取消链接,然后关闭它。这将使进程A的open成功,生成的FD将立即处于EOF。顺便说一句,如果您只是想进行开放式返回,那么取消链接是不必要的,但仍然是清理的好主意。

打开FIFO进行写入,取消链接,然后关闭它。这将使进程A的open成功,生成的FD将立即处于EOF。顺便说一句,如果您只是想进行开放式返回,那么取消链接是不必要的,但仍然是一个清理的好主意。

在Linux上,您可以在O_RDWR模式下不方便地打开FIFO。当您执行并保持FIFO时,其他打开程序不会在其打开的调用中被阻止,无论这些调用是只读的还是写打开的。然后,您可以在保持O_RDWR文件句柄的同时取消FIFO的链接

示例代码:

#include <unistd.h>
#include <stdio.h>
#include <fcntl.h>
int main(int C, char **V)
{
    int fd;
    if(0>(fd=open(V[1], O_RDWR))) return perror("open"),1;
    if(0>unlink(V[1])) return perror("unlink"),1;
}

在Linux上,您可以在O_RDWR模式下不方便地打开FIFO。当您执行并保持FIFO时,其他打开程序不会在其打开的调用中被阻止,无论这些调用是只读的还是写打开的。然后,您可以在保持O_RDWR文件句柄的同时取消FIFO的链接

示例代码:

#include <unistd.h>
#include <stdio.h>
#include <fcntl.h>
int main(int C, char **V)
{
    int fd;
    if(0>(fd=open(V[1], O_RDWR))) return perror("open"),1;
    if(0>unlink(V[1])) return perror("unlink"),1;
}

无效器应在非阻塞写入模式下打开FIFO。这样,如果没有读者在等待它,那么它对open的调用就不会挂起。然后它应该立即关闭FIFO

void invalidate() {
    int fd = open(path, O_WRONLY)
    unlink(path)
    close(fd)
}
当FIFO打开时,在只读打开中等待的任何进程都将返回。然后他们会立即读取EOF

void invalidate() {
    int fd = open(path, O_WRONLY | O_NONBLOCK);
    unlink(path);
    close(fd);
}

无效器应在非阻塞写入模式下打开FIFO。这样,如果没有读者在等待它,那么它对open的调用就不会挂起。然后它应该立即关闭FIFO

void invalidate() {
    int fd = open(path, O_WRONLY)
    unlink(path)
    close(fd)
}
当FIFO打开时,在只读打开中等待的任何进程都将返回。然后他们会立即读取EOF

void invalidate() {
    int fd = open(path, O_WRONLY | O_NONBLOCK);
    unlink(path);
    close(fd);
}


取消链接文件对已经引用该文件的进程没有影响。我认为没有办法实现您想要的。您可以使用非阻塞,程序必须定期检查链接是否仍然存在。我尝试了非阻塞,但这会带来其他问题,也就是说,我无法区分表示流结束的零字节写入。对openpath,O_RDONLY的调用应该在另一个进程执行openpath,O_WRONLY时立即返回,反之亦然。取消文件链接对已经引用该文件的进程没有影响。我认为没有办法执行您想要的操作。您可以使用非阻塞,程序必须定期检查链接是否仍然存在。我尝试了非阻塞,但这带来了其他问题,即我无法区分表示流结束的零字节写入。对openpath,O_RDONLY的调用应在另一个进程执行openpath,O_RDONLY,反之亦然。我试着写下并关闭它,但“打开”仍然挂起。@ErikAigner它对我有用。请将您尝试的代码编辑到您的问题中,包括正在阻止的程序和应该取消阻止的程序。更新了答案。@ErikAigner您根本不需要写入它。你只需要用O_WRONLY打开它。啊,是我的错。。。实际上我在这里开了个玩笑。从我的错误记忆中写下了这一点。已修复。我尝试写入并关闭它,但“打开”仍然挂起。@ErikAigner它对我有效。请将您尝试的代码编辑到您的问题中,包括正在阻止的程序和应该取消阻止的程序。更新了答案。@ErikAigner您根本不需要写入它。你只需要用O_WRONLY打开它。啊,是我的错。。。实际上我在这里开了个玩笑。从我的错误记忆中写下了这一点。修好了,我想我现在明白了。我需要结合使用open with O_NONBLOCK和处理另一端的EINTR。如果另一端正在打开进行写入,关闭读取端将导致它在尝试写入时获得SIGPIPE信号。我使用O_RDWR进行了一个小的修改,以取消阻止任何等待的openfd、O_WRONLY调用。我想我现在已经解决了。我需要一个open with O_NONBLOCK和处理另一侧的EINTR的组合。如果另一侧为写入而打开,则关闭读取侧将使其获得SIGPIPE信号w
当它试图写的时候。我做了一个小小的修改,使用O_RDWR也解锁了任何等待的openfd,O_WRONLY调用。哦,我读到有点晚了,sry,同时我自己想出了O_RDWR的窍门。^^^@ErikAigner它在MacOS上也能半工作。至少是O_RDWR部分。但在那里,它似乎只打开了等待fifo的一个开场白。在Linux上,它会解除所有这些限制,例如,假设您有多个cat fifo或cat fifo。在Cygwin上,我得到了O_RDWR的EPERM。我想可以用两个线程来解决。哦,我读得有点晚了,sry,同时我自己想出了O_RDWR技巧^^^@ErikAigner It semi在MacOS上也能工作。至少是O_RDWR部分。但在那里,它似乎只打开了等待fifo的一个开场白。在Linux上,它会解除所有这些限制,例如,假设您有多个cat fifo或cat fifo。在Cygwin上,我得到了O_RDWR的EPERM。我想可以用两个线程来处理。