C++双向管道-在循环中尝试从子进程读取时卡住



我正在尝试制作一个双向管道,使父进程子进程发送消息并等待其答案,对答案执行某些操作并发送另一条消息,然后一次又一次地重复
子进程使用STDIN和STDOUT来接收和发送输入,父进程++字符串,因此它们在发送前和接收后进行转换,而且不同的消息具有不同的(未知)长度
我写了一个简单的代码来举例说明:

Parent.cpp:

#include <unistd.h>
#include <iostream>
#include <cstring>
#include <string>
int main(){
int parent_to_child[2];
int child_to_parent[2];
pipe(parent_to_child);
pipe(child_to_parent);
int childPID = fork();
if(childPID == 0){
//this is child
close(parent_to_child[1]);//Close the writing end of the incoming pipe
close(child_to_parent[0]);//Close the reading end of the outgoing pipe
dup2(parent_to_child[0], STDIN_FILENO);//replace stdin with incoming pipe
dup2(child_to_parent[1], STDOUT_FILENO);//replace stdout with outgoing pipe
//exec child process
char filename[] = "child.out";
char *newargv[] = { NULL };
char *newenviron[] = { NULL };
execve(filename, newargv, newenviron);
}else{
//this is parent
close(parent_to_child[0]);//Close the reading end of the outgoing pipe.
close(child_to_parent[1]);//Close the writing side of the incoming pipe.
int parent_frame = 0;
char str_to_write[100];
char reading_buffer;
std::string received_str;
do{
//Make the frame number a cstring and append 'n'
strcpy(str_to_write, std::to_string(parent_frame).c_str());
strcat(str_to_write,"n");
write(parent_to_child[1], str_to_write, strlen(str_to_write));
std::cout << "Parent sent: "<< str_to_write <<std::endl;

received_str = "";
while(read(child_to_parent[0], &reading_buffer, 1) > 0){
received_str += reading_buffer;
}
std::cout << "Parent received: "<< received_str<< std::endl;
} while (++parent_frame);
}
return 0;
}

Child.cpp

#include <unistd.h>
#include <iostream>
int main(){
int child_frame = 0;
char child_buffer[1024];
do{
std::cin >> child_buffer; //wait for father's messages
std::cout << "CHILD received: "<< child_buffer<<" at frame "<< child_frame<<"n"; //return message to father
}while(++child_frame);
return 0;
}

执行父输出:

Parent sent: 0

并被卡住

如果我不使管道从子级到父级,并让父级写入STDOUT,那么代码的工作方式就像我在终端中看到的子级的响应一样。因此,表示子代能够从父代读取,但由于某种原因,父代不能从子代读取。

所以我的问题是:为什么父母不能读取孩子的输出,这怎么可能呢?我做错了什么?

问题在于最内层while循环中父级对read(2)的调用。

这是连续读取数据,直到read(2)返回值<=0。但只有当(1)发生错误或(2)子级关闭管道的写入端时,才会发生这种情况。因此,孩子会发送消息,家长会很高兴地阅读,然后就坐在那里等待孩子的进一步数据。这显然永远不会到来。

问题在于while循环中的条件。您不想在EOF或错误之前读取,您想读取整行(如果您使用换行符作为消息分隔符)。看看getline(3)可以让这变得更容易,避免一次读取单个字节,或者std::getline,如果你把代码变成C++风格的话。

最新更新