c - POSIX FIFO 在阻塞模式下打开时冻结
问题描述
默认情况下,POSIX FIFO 在阻塞模式下打开。我的问题是,当我以阻塞模式打开它时,它只会冻结(阻塞)而没有其他任何反应。
最初我用 RDWR 标志打开了两边,我没有问题,因为 RDWR 使它成为非阻塞,因为“在 Linux 下,打开一个 FIFO 进行读写将在阻塞和非阻塞模式下都成功”(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
但随后腻子终端冻结(阻塞),没有其他任何事情发生。我从来没有到达打开阅读面的街区。具体来说,它会在上面的 fifo_open 代码中到达 perror("open") 之前阻塞:
根据https://www.man7.org/linux/man-pages/man7/fifo.7.html上的 Linux 手册页,“通常,打开 FIFO 块直到另一端也打开。” 太好了,但我无法打开编写器的代码,因为阅读器阻止了所有进一步的进展。这就像墨西哥的对峙。
当然一定有办法,但我的研究还没有找到。
感谢您对此的任何帮助。
解决方案
三个选项:
- FIFO 本身不会在非阻塞模式下丢弃消息。如果您的代码正在丢弃消息,请修复您的代码以停止这样做,然后使用非阻塞模式。
- 以非阻塞模式打开 FIFO,然后在两端打开后,使用
fcntl
将其更改为阻塞模式。 - 使用单独的线程或进程打开 FIFO 的每一半。
推荐阅读
- java - 我的方法是未定义的,不会让吸气剂工作
- json - 如何使用 c# 将这个大型 json 文件加载到对象或数据集中?
- octobercms - 以不同的方式查看第一个帖子,其他的都一样 OCTOBERCMS(Rainlab 博客)
- python - 暂停后使用pygame时游戏冻结
- php - php注销脚本中注销的问题
- go - 用于文档目的的类型别名
- flutter - Flutter 无法使用 PageTransitionSwitcher 保持选项卡的状态
- angular - 如何在 ng2 圆环图中的数据集之间添加空格
- sql - 收藏品进入循环
- python - 在序列化程序 Django 中求和数据