POSIX FIFO 在阻塞模式下打开时冻结
POSIX FIFO freezes when opened in blocking mode
默认情况下,POSIX FIFO 以阻塞模式打开。我的问题是,当我以阻塞模式打开它时,它只是冻结(阻塞)并且没有其他任何事情发生。
最初我用 RDWR 标志打开两侧,我没有遇到任何问题,因为 RDWR 使它成为非阻塞,因为 "Under Linux, opening a FIFO for read and write will succeed both in blocking and nonblocking mode" (https://linux.die.net/man/7/fifo)。但是在非阻塞模式下我有时会丢失记录,所以我需要以阻塞模式打开它。
我是这样调用 mkfifo 的:
int64_t fifo_setup(char * fifo_name)
{
if (mkfifo(fifo_name, S_IWUSR | S_IRUSR | S_IRGRP | S_IROTH) == -1) {
perror("mkfifo");
exit(EXIT_FAILURE); }
return 0; }
我原来的打开电话:
int64_t fifo_open(char * fifo_name, int64_t read_write) {
int c;
if (read_write == 1) {
c = open(fifo_name, O_RDWR);}
if (read_write == 2) {
c = open(fifo_name, O_RDWR);}
perror("open");
return (c);
}
然后我改成了:
int64_t fifo_open(char * fifo_name, int64_t read_write) {
int c;
if (read_write == 1) {
c = open(fifo_name, O_WRONLY);}
if (read_write == 2) {
c = open(fifo_name, O_RDONLY);}
perror("open");
return (c);
}
我的程序达到编写器线程的开放调用(这是对 C 的 NASM 调用):
Open_FIFO_Write:
lea rdi,[fifo_name]
mov rsi,1
call fifo_open wrt ..plt
mov [fifo_write_fd],rax
但是随后 Putty 终端冻结(阻塞)并且没有其他任何事情发生。我从来没有到达打开阅读面的街区。具体来说,它会在上面的 fifo_open 代码中到达 perror("open") 之前阻塞:
根据 https://www.man7.org/linux/man-pages/man7/fifo.7.html 的 Linux 手册页,"Normally, opening the FIFO blocks until the other end is opened also." 很好,但我无法找到打开编写器的代码,因为 reader 块所有进一步的进展。这就像墨西哥的对峙。
当然一定有办法,但我的研究还没有找到。
感谢您对此提供的任何帮助。
三个选项:
- FIFO 本身不会在非阻塞模式下丢弃消息。如果您的代码正在丢弃消息,请修复您的代码以停止这样做,然后只使用非阻塞模式。
- 以非阻塞模式打开FIFO,然后在两端打开后,使用
fcntl
将其更改为阻塞模式。
- 使用单独的线程或进程打开 FIFO 的每一半。
默认情况下,POSIX FIFO 以阻塞模式打开。我的问题是,当我以阻塞模式打开它时,它只是冻结(阻塞)并且没有其他任何事情发生。
最初我用 RDWR 标志打开两侧,我没有遇到任何问题,因为 RDWR 使它成为非阻塞,因为 "Under Linux, opening a FIFO for read and write will succeed both in blocking and nonblocking mode" (https://linux.die.net/man/7/fifo)。但是在非阻塞模式下我有时会丢失记录,所以我需要以阻塞模式打开它。
我是这样调用 mkfifo 的:
int64_t fifo_setup(char * fifo_name)
{
if (mkfifo(fifo_name, S_IWUSR | S_IRUSR | S_IRGRP | S_IROTH) == -1) {
perror("mkfifo");
exit(EXIT_FAILURE); }
return 0; }
我原来的打开电话:
int64_t fifo_open(char * fifo_name, int64_t read_write) {
int c;
if (read_write == 1) {
c = open(fifo_name, O_RDWR);}
if (read_write == 2) {
c = open(fifo_name, O_RDWR);}
perror("open");
return (c);
}
然后我改成了:
int64_t fifo_open(char * fifo_name, int64_t read_write) {
int c;
if (read_write == 1) {
c = open(fifo_name, O_WRONLY);}
if (read_write == 2) {
c = open(fifo_name, O_RDONLY);}
perror("open");
return (c);
}
我的程序达到编写器线程的开放调用(这是对 C 的 NASM 调用):
Open_FIFO_Write:
lea rdi,[fifo_name]
mov rsi,1
call fifo_open wrt ..plt
mov [fifo_write_fd],rax
但是随后 Putty 终端冻结(阻塞)并且没有其他任何事情发生。我从来没有到达打开阅读面的街区。具体来说,它会在上面的 fifo_open 代码中到达 perror("open") 之前阻塞:
根据 https://www.man7.org/linux/man-pages/man7/fifo.7.html 的 Linux 手册页,"Normally, opening the FIFO blocks until the other end is opened also." 很好,但我无法找到打开编写器的代码,因为 reader 块所有进一步的进展。这就像墨西哥的对峙。
当然一定有办法,但我的研究还没有找到。
感谢您对此提供的任何帮助。
三个选项:
- FIFO 本身不会在非阻塞模式下丢弃消息。如果您的代码正在丢弃消息,请修复您的代码以停止这样做,然后只使用非阻塞模式。
- 以非阻塞模式打开FIFO,然后在两端打开后,使用
fcntl
将其更改为阻塞模式。 - 使用单独的线程或进程打开 FIFO 的每一半。