c++ - 在进程中对同一管道进行读取和写入时出现 C++ 管道问题
问题描述
我正在学习管道和叉子。我试图通过使用管道和叉子来表示 kworker 进程的计数ps -A | grep kworker | wc -l
。我的代码工作正常,直到我为 grep 语句做管道。
我像这样运行我的代码:./a.out kworker
#include <iostream>
#include <unistd.h> // for fork()
#include <sys/wait.h> // for wait()
using std::cout;
using std::endl;
int main(int num = 1, char * args[] = NULL)
{
int pipefd[2];
pipe(pipefd);
char * p[3];
/*
wait for grandchild to complete ps - A
wait for child to complete grep kworker
execute wc -l
*/
p[2] = NULL;
pid_t id1 = fork(); // get child process
if(id1 == -1)
{
perror("fork");
close(pipefd[0]);
close(pipefd[1]);
}
else if(id1 == 0) // child process
{
pid_t id2 = fork(); // get grandchild process
if(id2 == 0) // grandchild process
{
p[0] = "ps";
p[1] = "-A";
dup2(pipefd[1], STDOUT_FILENO);
close(pipefd[0]); // close read
close(pipefd[1]);
execvp(p[0], p);
perror("exec");
exit(1);
}
else if(id2 > 0) // child process
{
// The problem is in this if-statement
close(pipefd[1]);
wait(0);
p[0] = "grep";
p[1] = args[1];
// I get output from the STDOUT
dup2(pipefd[0], STDIN_FILENO); // read from pipe
dup2(pipefd[1], STDOUT_FILENO); // write to pipe
close(pipefd[1]);
execvp(p[0], p);
}
}
else if(id1 > 0) // parent process
{
// close pipes first
close(pipefd[1]); // close unused write end
wait(0);
p[0] = "wc";
p[1] = "-l";
dup2(pipefd[0], STDIN_FILENO); // read from pipe
close(pipefd[1]);
close(pipefd[0]);
if(execvp(p[0], p) == -1)
{
perror("exec");
exit(1);
}
}
}
代码给我的输出:
6 ? 00:00:00 kworker/0:0H-events_highpri
20 ? 00:00:00 kworker/1:0H-kblockd
26 ? 00:00:00 kworker/2:0H-kblockd
32 ? 00:00:00 kworker/3:0H-kblockd
50 ? 00:00:00 kworker/1:1-events
172 ? 00:00:00 kworker/u17:0-rb_allocator
289 ? 00:00:00 kworker/3:1H
290 ? 00:00:00 kworker/1:1H-events_highpri
296 ? 00:00:00 kworker/0:1H-kblockd
360 ? 00:00:00 kworker/2:1H-events_highpri
550 ? 00:00:00 kworker/u17:1-rb_allocator
1340 ? 00:00:01 kworker/2:4-events
1374 ? 00:00:00 kworker/0:0-events
2751 ? 00:00:00 kworker/3:2-events
2782 ? 00:00:00 kworker/1:2-mm_percpu_wq
5389 ? 00:00:00 kworker/0:1-events
6539 ? 00:00:00 kworker/u16:3-events_unbound
6599 ? 00:00:00 kworker/3:1
6618 ? 00:00:00 kworker/2:1-events
6705 ? 00:00:00 kworker/u16:0-events_unbound
6815 ? 00:00:00 kworker/u16:1-events_unbound
7283 ? 00:00:00 kworker/u16:2-events_unbound
0
我期望输出与以下内容相同:
ps -A | grep kworker | wc -l
21
什么可能导致此问题?我在这里查看了其他问题,但找不到解决方案。
添加第二个管道解决了这个问题。我们不能同时读取和写入同一个管道。
解决方案
看:
close(pipefd[1]);
dup2(pipefd[1], STDOUT_FILENO);
您关闭其中一个 FD。然后你使用 dup2 。因为 FD 已关闭,所以 dup2 返回错误代码并且不执行任何操作。所以grep的stdout还是正常的stdout。
您的代码还有其他问题。这是你问的那个。
关于“其他问题”的详细说明:您的代码尝试使用相同的管道两次。ps
并grep
从管道中读取,并grep
从wc
管道中读取。这意味着数据可以ps
直接从 到wc
或从grep
返回到自身,这不是您想要的。您应该使用两个单独的管道 - 一个用于连接ps
,一个用于grep
连接。grep
wc
推荐阅读
- flutter - Flutter Firebase 身份验证模拟器启用
- r - 检查两个文本字符串中文本的相似性
- c++ - 类函数宏扩展为空
- salesforce - Salesforce SOQL 或 SOSL 中是否有 SOQL 函数将日期转换为 Unix 时间戳?
- latex - Latex 中的多列
- python - Ansible:根据特定事实计算主机
- swift - 用户凭证 - 使用 Apple 登录 (SwiftUI)
- outlook - 在 Outlook 加载项中获取浏览器 URL
- c# - 我的通用 Windows 平台软件是否能够获得启动关机所需的权限?
- physics - 1e-26 到 1e-15 的大数量级的参数缩放?