先进先出:一个进程永远不会从管道读取
FIFO: One process never reads from pipe
我正在遵循 Linux Piping 的 THIS TutorialsPoint 指南,我特别需要使用 FIFO。
但是,该代码根本不适用于服务器端。
服务器文件要么无限期挂起,要么什么都不读取,而客户端则写入 FIFO 并立即读取它刚刚写入的内容。
以下是这两个文件的完整代码,以防您不想通过TutorialsPoint:
fifoserver_twoway.cpp
#include <stdio.h>
#include <sys/stat.h>
#include <sys/types.h>
#include <fcntl.h>
#include <unistd.h>
#include <string.h>
#define FIFO_FILE "/tmp/fifo_twoway"
void reverse_string(char *);
int main() {
int fd;
char readbuf[80];
char end[10];
int to_end;
int read_bytes;
/* Create the FIFO if it does not exist */
mkfifo(FIFO_FILE, S_IFIFO|0640);
strcpy(end, "end");
fd = open(FIFO_FILE, O_RDWR);
while(1) {
read_bytes = read(fd, readbuf, sizeof(readbuf));
readbuf[read_bytes] = ' ';
printf("FIFOSERVER: Received string: "%s" and length is %dn", readbuf, (int)strlen(readbuf));
to_end = strcmp(readbuf, end);
if (to_end == 0) {
close(fd);
break;
}
reverse_string(readbuf);
printf("FIFOSERVER: Sending Reversed String: "%s" and length is %dn", readbuf, (int) strlen(readbuf));
write(fd, readbuf, strlen(readbuf));
/*
sleep - This is to make sure other process reads this, otherwise this
process would retrieve the message
*/
sleep(2);
}
return 0;
}
void reverse_string(char *str) {
int last, limit, first;
char temp;
last = strlen(str) - 1;
limit = last/2;
first = 0;
while (first < last) {
temp = str[first];
str[first] = str[last];
str[last] = temp;
first++;
last--;
}
return;
}
fifoclient_twoway.cpp
#include <stdio.h>
#include <sys/stat.h>
#include <sys/types.h>
#include <fcntl.h>
#include <unistd.h>
#include <string.h>
#define FIFO_FILE "/tmp/fifo_twoway"
int main() {
int fd;
int end_process;
int stringlen;
int read_bytes;
char readbuf[80];
char end_str[5];
printf("FIFO_CLIENT: Send messages, infinitely, to end enter "end"n");
fd = open(FIFO_FILE, O_CREAT|O_RDWR);
strcpy(end_str, "end");
while (1) {
printf("Enter string: ");
fgets(readbuf, sizeof(readbuf), stdin);
stringlen = strlen(readbuf);
readbuf[stringlen - 1] = ' ';
end_process = strcmp(readbuf, end_str);
//printf("end_process is %dn", end_process);
if (end_process != 0) {
write(fd, readbuf, strlen(readbuf));
printf("FIFOCLIENT: Sent string: "%s" and string length is %dn", readbuf, (int)strlen(readbuf));
read_bytes = read(fd, readbuf, sizeof(readbuf));
readbuf[read_bytes] = ' ';
printf("FIFOCLIENT: Received string: "%s" and length is %dn", readbuf, (int)strlen(readbuf));
} else {
write(fd, readbuf, strlen(readbuf));
printf("FIFOCLIENT: Sent string: "%s" and string length is %dn", readbuf, (int)strlen(readbuf));
close(fd);
break;
}
}
return 0;
}
当我运行这两个进程时,这就是我得到的:
./fifoserver_twoway
FIFOSERVER: Received string: "" and length is 0
FIFOSERVER: Sending Reversed String: "" and length is 0
FIFOSERVER: Received string: "" and length is 0
FIFOSERVER: Sending Reversed String: "" and length is 0
./fifoclient_twoway
FIFOCLIENT: Sent string: "ciao" and string length is 4
FIFOCLIENT: Received string: "ciao" and length is 4
Enter string: why won't you reverse?
FIFOCLIENT: Sent string: "why won't you reverse?" and string length is 29
FIFOCLIENT: Received string: "why won't you reverse?" and length is 29
还值得注意的是,在开始编写这个问题之前,服务器的行为完全不同:它不会像您在这里看到的那样接收任何内容并打印,而是在"读取"后无限期挂起(除了更改FIFO_FILE路径外,我没有更改代码一点(
你让服务器在写入后进入睡眠状态 - 但客户端不睡觉。这样,客户端仍然可以在服务器获取输出之前读回自己的输出。因此,至少您应该在两次写入后添加睡眠,让服务器休眠更长时间,以确保客户端首先唤醒以读取服务器输出。
同时访问未命名管道的同一端(通过管道函数创建(是未定义的行为。虽然不确定命名管道,但我认为那里也几乎相同。通过简单的延迟(sleep
,usleep
(将并发访问同步到这些末端也许可以解决问题,但这是一种非常不安全的方法。
我宁愿推荐两个单独的管道(正如Tony Tannous已经提出的那样(,每个方向一个(根据需要打开各自的两端RDONLY
或WRONLY
(,然后你会得到全双工通信而不是半双工,你也不需要进一步的同步(大多数简单变体的延迟(:
// server
int fd_cs = open(FIFO_FILE_CS, O_RDONLY);
int fd_sc = open(FIFO_FILE_SC, O_WRONLY);
read(fd_cs, ...);
write(fd_sc, ...);
// client
int fd_cs = open(FIFO_FILE_CS, O_WRONLY);
int fd_sc = open(FIFO_FILE_SC, O_RDONLY);
write(fd_cs, ...);
read(fd_sc, ...);
相关文章:
- 理解boost::asio-async_read在无需读取内容时的行为
- 使用新行和不使用新行读取文件
- 读取文件并输入到矢量中
- 用c++从输入文件中读取另一行
- 读取文件的最后一行并输入到链接列表时出错
- 在进程中对同一管道进行读取和写入时C++管道出现问题
- 无法找到/读取配置文件.conf-FileIOException
- 如何使用Luacneneneba API正确读取字符串和表参数
- C++将文本文件中的数据读取到结构数组中
- 正在将csv文件读取为双精度矢量
- 为什么 sscanf 无法从一个字符串中读取uint64_t和字符?
- 为什么在读取文件大小时文件IO速度会发生变化
- 正在读取二进制文件(is_open)
- 如何在c++中从文本文件中逐行读取整数
- 我想在C++中读取一些多个字符,但它永远不会读取第二个字符
- 先进先出:一个进程永远不会从管道读取
- 无法从串行端口读取.WaitCommEvent() 永远不会返回
- 未定义的行为怪癖:在缓冲区外读取导致循环永远不会终止
- 为什么 ReadFile() 不返回 0 ?程序尝试永远从管道读取数据
- 当其他线程正在等待读取时,写入串口将永远阻塞