gpt4 book ai didi

c++ - 没有从管道中获取所有线路

转载 作者:太空宇宙 更新时间:2023-11-04 04:02:59 26 4
gpt4 key购买 nike

我正在完成一项任务,其中需要几个进程(父进程和子进程)进行通信。父级将文件路径发送给子级,子级必须在其上运行 linux file (/usr/bin/file),并将输出返回给父级。

目前我仍在努力让一个 child 工作,所以现在我假设有一个 child 。

我打算向每个子级发送多个文件路径(一批文件),然后读取file的输出。

问题:

我使用循环来写入一些文件路径,但是当我读取 child 的输出管道时,我没有得到我应该得到的所有输出。

代码:

#define Read            0
#define Write 1
#define ParentRead read_pipe[0]
#define ParentWrite write_pipe[1]
#define ChildRead write_pipe[0]
#define ChildWrite read_pipe[1]
#define PIPE_BUF_LEN 4096

using namespace std;
int main()
{
/** Pipe for reading for subprocess */
int read_pipe[2];
/** Pipe for writing to subprocess */
int write_pipe[2];
char buffer[PIPE_BUF_LEN] = "";
if (pipe(read_pipe) == 0 && pipe(write_pipe) == 0)
{
pid_t pid = fork();
if (pid == -1)
{
fprintf(stderr, "Fork failure");
exit(EXIT_FAILURE);
}
else if (pid == 0) //Child process
{
close(ParentRead);
close(ParentWrite);
dup2 (ChildRead, STDIN_FILENO); /*redirect ChildRead to stdin*/
dup2 (ChildWrite, STDOUT_FILENO); /*redirect stdout to ChildWrite*/
char* paramArgs[]={"/usr/bin/file","-n","-f-",NULL};
execv("/usr/bin/file",paramArgs);
exit(EXIT_FAILURE);
}
else { //Parent process
close(ChildRead);
close(ChildWrite);

for (int i=0; i < 3 ;i++)
{
/*write to processes which are ready for writing: */
fd_set rfds;
int retval;
FD_ZERO(&rfds);
FD_SET(ParentWrite, &rfds);
retval = select(10, NULL, &rfds, NULL, NULL);
if (retval == -1)
{
perror("select()");
}
else if (retval)
{
write(ParentWrite, "file1\nfile2\n", 12);
}
/*read from processes which are ready for reading*/
FD_ZERO(&rfds);
FD_SET(ParentRead, &rfds);
retval = select(10, &rfds, NULL, NULL, NULL);
if (retval == -1)
{
perror("select()");
}
else if (retval)
{
read(ParentRead, buffer, PIPE_BUF_LEN);
cout << buffer;
}
}
}
}
exit(EXIT_SUCCESS);
}

在本例中,我尝试在 3 次迭代的循环中对“file1\nfile2\n”(注意使用的 -n -f- 标志)运行 file,期望获得六行,但只获得三行:

file1: ERROR: cannot open `file1' (No such file or directory)

file2: ERROR: cannot open `file2' (No such file or directory)

file1: ERROR: cannot open `file1' (No such file or directory)

当我不将子进程的输出重定向到管道(让它写入 std_out)时,我确实得到了所有六行。

任何帮助将不胜感激。

最佳答案

调度程序。您处于一个循环中,要求子进程(即 pgm file)查找两个文件三次。您只需在父级中的每个循环中执行一次读取。

  • 如果子进程被调度且不间断,它将执行第一次文件查找,写入管道,执行第二次查找,写入管道。家长得到安排,您可以一口气读完 child 的完整输出。你是金子(但很幸运)。
  • 子进程已被调度,执行第一次查找和管道写入并被中断。父级读取一个输出。 child 被重新安排并进行第二次查找并写入管道。父级读取一个输出。因为您只读取了 3 次,所以最终只读取了 6 个输出中的 3 个。
  • 上述内容的变体。也许您会读取 1 个输出,然后读取 3 个输出,然后读取 1 个输出。您只是不知道。

请注意,您至少在每次读取时获得完整的子输出的原因是,如果管道写入低于 PIPE_BUF 长度,则保证它们是原子的。如果您在套接字上使用这种例程,您最终可能会在每次读取时获得消息的小数部分。

解决方案:您必须循环读取,直到获得所需的字节数(或完整消息)。在这种情况下,我假设 file 的输出始终是一个以换行符结尾的字符串。但是您每次循环都要求两个 file 输出。因此,请阅读直到满足该条件,即直到读到两个完整的字符串。

关于c++ - 没有从管道中获取所有线路,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/22363935/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com