wait 命令不会等待子进程完成 c cpp c++

2023-12-23

我正在尝试编写一个 C++ 程序,该程序创建一个子进程、运行一个命令并将输出通过管道返回到父进程正在运行的命令的输入。

我让父级执行 wait(NULL) 或 wait((void*)pid) 命令,但它不等待。

这是代码:

#include <string.h>
#include <fstream>
#include <iostream>
#include <unistd.h>
#include <stdio.h>
#include <sys/wait.h>
using namespace std;

int main(int argc, char * argv[])
{    
        char* commands[strlen(argv[1])];
        char *command = NULL;
        command = strtok(argv[1],"|");
        int i = 0;
        while(command != NULL)
        {
                commands[i] = command;
                i++;
                command = strtok(NULL,"|");
        }

        int numberOfCommands = i;

        pid_t pid;
        int pfd[2];
        char* prgname = NULL;
        if(pipe(pfd) == -1)
        {
                perror("error on pipe call");
                return(1);
        }

        for(int j = 0;j<numberOfCommands;j++)
        {
                cout<<commands[j]<<endl;
        }

        pid = fork();
        if(pid == 0){//child process
                printf("Child: My PID = %d\n", getpid());
                printf("Child: Running...\n");
                close(pfd[0]); //close read end of pipe
                dup2(pfd[1],1);//connect the pipes
                close(pfd[1]);//close extra file descriptors
                prgname = commands[0];//first command
                cout<<"child starting command: "<<prgname<<endl;
                execlp(prgname, prgname, 0);//Load the program
                **printf("Child: Done sleeping, returning.\n");**
        }
        else
        {
                printf("Parent: My PID = %d\n", getpid());
                **wait((void*)pid); //also tried wait(NULL); same effect
                printf("Parent: Running...\n");**
                close(pfd[1]); //close the write end of the pipe
                dup2(pfd[0],0);//connect the pipes
                close(pfd[0]); //close extra file descriptor
                prgname = commands[1];//now run the second command
                cout<<"parent starting command: "<<prgname<<endl;
                execlp(prgname, prgname, 0);//Load the programm
        }
        cout<<"all done"<<endl;
        return 0;
}

不要考虑粗体线。我希望父进程在 wait() 命令处等待,子进程会打印出“Child did sleep...”,然后完成,然后父进程会打印出“Parent: running...”

我究竟做错了什么!

Thanks!

更新:程序的完整输出为:

dmegs
more
Child: My PID = 30070
Child: Running...
Parent: My PID = 30066
Parent: Running...
parent starting command: more
child starting command: dmegs
Child: Done sleeping, returning.
all done

我看到四个问题:

1) execlp()失败了:execlp()(或任何exec如果成功的话,它会完全替换当前正在运行的进程映像 - 除非出现问题,否则预计不会返回。但您看到的是“孩子:睡觉完毕,正在返回”消息,因此它不可能成功。 (在你的例子中,我猜这可能是因为dmegs本来应该dmesg.)

2) printf() and cout输出缓冲意味着无法保证您按照发生的顺序获得输出。如果你想通过打印输出来调试它,你最好打印到stderr(例如与fprintf(stderr, ...))(默认情况下)是无缓冲的。

3)正如其他人指出的,wait((void *)pid)是错的。wait(NULL) or waitpid(pid, NULL, 0).

4)这是否是一个问题取决于平台,但是......终止空指针参数execlp()应明确写为(char *)0而不仅仅是0,以确保它作为指针而不是整数传递。一般来说,在C语言中,0根据定义,在指针上下文中是空指针,但是当将参数传递给具有可变数量参数的函数时,编译器没有足够的信息来知道您正在尝试在指针上下文中使用它,因此将其传递为一个整数,除非你显式地转换它。在指针和整数大小不同的平台上,这可能会给您带来麻烦。


所以我认为wait()正在工作,子进程实际上并没有运行您想要的命令,并且父进程和子进程的输出由于缓冲而变得混乱。


这是代码的稍微修改版本,它不使用任何 C++,删除了命令处理内容,并且仅通过管道输出sleep 5 to cat(这是毫无意义的,因为sleep无论如何都不会生成任何输出,但延迟对于查看发生的情况很有用):

#include <string.h>
#include <unistd.h>
#include <stdio.h>
#include <sys/types.h>
#include <sys/wait.h>

int main(void)
{    
        pid_t pid;
        int pfd[2];
        if(pipe(pfd) == -1)
        {
                perror("error on pipe call");
                return(1);
        }

        pid = fork();
        if(pid == 0){//child process
                fprintf(stderr, "Child: My PID = %d\n", getpid());
                fprintf(stderr, "Child: Running...\n");
                close(pfd[0]); //close read end of pipe
                dup2(pfd[1],1);//connect the pipes
                close(pfd[1]);//close extra file descriptors
                fprintf(stderr, "child starting command: sleep 5\n");
                execlp("sleep", "sleep", "5", (char *)0);//Load the program
                fprintf(stderr, "child: execlp failed\n");
        }
        else
        {
                fprintf(stderr,"Parent: My PID = %d\n", getpid());
                wait(NULL);
                fprintf(stderr,"Parent: Running...\n");
                close(pfd[1]); //close the write end of the pipe
                dup2(pfd[0],0);//connect the pipes
                close(pfd[0]); //close extra file descriptor
                fprintf(stderr,"parent starting command: cat\n");
                execlp("cat", "cat", (char *)0);//Load the programm
        }
        fprintf(stderr,"all done\n");
        return 0;
}

Output:

$ gcc -Wall -o wait wait.c
$ ./wait
Child: My PID = 27846
Child: Running...
child starting command: sleep 5
Parent: My PID = 27845

(这里有5秒的延迟)

Parent: Running...
parent starting command: cat
$
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

wait 命令不会等待子进程完成 c cpp c++ 的相关文章

  • 带有 Windows 窗体应用程序的地图

    我正在构建一个需要地图的 C Winforms 应用程序 例如 Google 地图 Bing 地图等 但我对 ToU 许可 非商业使用等感到非常困惑 我的问题 您建议将哪个地图提供商 最好是免费的 嵌入到 winforms 应用程序中以用于
  • 如何在自定义保存操作 WFFM 中获取 Sitecore.Current.Site 对象?

    我在用着面向营销人员的 Sitecore 网络表单 在里面save action我得到的表格Sitecore Context Site对象 但该对象没有返回正确的上下文 该值为 modules shell 有谁知道我如何才能获得正确的上下文
  • 你好世界,裸机 Beagleboard

    我正在尝试在我的 Beagleboard xm rev 上运行 hello world 类型的程序 C 通过调用 Cputs功能来自装配 到目前为止 我一直使用这个作为参考 http wiki osdev org ARM Beagleboa
  • 任务计划程序控制台输出在哪里? (C# 控制台应用程序)

    我正在运行 C Windows 控制台应用程序 并通过任务计划程序传递几个参数 它全天运行 将其他应用程序创建的平面文件数据加载到 SQL Server 中 该程序间歇性失败 并且我有 Try Catch 逻辑 该逻辑使用 Console
  • 递归显式模板实例化可能吗?

    给定一个类似的模板 template
  • C++ 编译器可以对结构中的元素重新排序吗

    C 编译器 特别是 g 可以对结构体的内部元素重新排序吗 我看到一些奇怪的行为 其中我有一个包含如下内容的结构 Struct SomeStruct long someLong long someLongArray 25 unsigned l
  • Web API 复杂参数属性均为 null

    我有一个 Web API 服务调用可以更新用户的首选项 不幸的是 当我从 jQuery ajax 调用中调用此 POST 方法时 请求参数对象的属性始终为 null 或默认值 而不是传入的值 如果我使用 REST 客户端调用相同的方法 我使
  • C# 从整数反序列化枚举

    是否可以从 C 中的 int 反序列化枚举 例如如果我有以下课程 class Employee public string Name get set public int EmployeeTypeID get set 我可以轻松地从 XML
  • 使用 boost::asio 是否有一种可移植的方法来查找空闲端口号

    我目前正在尝试找出一种方法来查找空闲端口号以建立连接 最好使用 boost asio 然后 该端口号将用于侦听 只有这样我才能打开套接字 大致来说 有没有办法做到 tcp resolver query query localhost por
  • C# 中 value 为匿名类型的字典

    是否可以在 C 中创建一个System Collections Generic Dictionary
  • flowlayoutpanel和水平滚动条问题

    我正在使用一个 flowlayoutpanel 它有很多逻辑上的按钮 我遇到的问题是 当我调整窗口大小时 当窗口变小时 我无法看到所有水平排列的按钮 相反 当窗口变小时 按钮会下降到下一行 谁能帮我解决这个问题 我只是希望按钮水平排列 当窗
  • 驱蚊程序?

    不 我认真的 最近 我读到 当电脑的压电蜂鸣器以一定频率振动时 声音可以驱赶蚊子 真的吗 如何以编程方式访问 PC 蜂鸣器 而不是扬声器 最好使用 C 我不知道有没有蚊子 但我的头疼得要命 啊啊 using System Runtime I
  • 在 C# 中给定周数和年份,计算一周的开始和结束日期(基于 ISO 规范)

    我需要生成一份报告 显示一年中的 52 周 或某些年份的 53 周 及其开始日期和结束日期 有一个 ISO 规范可以做到这一点 但看起来非常复杂 我希望有人知道在 C 或 Visual Basic 中执行此操作的方法 实际上适用于 Visu
  • 将控制台输入和输出重定向到文本框

    您好 提前致谢 我正在尝试 非常努力 将控制台输入和输出重定向到文本框 到目前为止 输出工作正常 但问题在于输入 例如 我无法执行一个简单的程序来执行以下操作 Console WriteLine 请输入您的姓名 字符串名称 Console
  • 如何从 MongoDB 中的 ChangeStream 过滤对特定字段的更新

    我正在设置一个 ChangeStream 以便在集合中的文档发生更改时通知我 以便我可以将该文档的 LastModified 元素更新插入到事件发生的时间 由于此更新将导致 ChangeStream 上发生新事件 因此我需要过滤掉这些更新以
  • 使用 c++20 范围删除最后一个元素的最佳方法是什么

    有没有比反转两次更好的方法来使用 c 20 范围删除容器中的最后一个元素 include
  • 如何设置扬声器声音增强设置

    如何以编程方式设置 Windows 扬声器设置 增强 选项卡 中可用的声音效果 恐怕这是不可能的 参见 Maurits 对他的评论blog http blogs msdn com b matthew van eerde archive 20
  • 为 winforms ComboBox 中的单个项目着色?

    我遇到了一个困境 我有一个表单 其中包含许多组合框 其中包含在某些情况下可能无效 过时的信息 选项 项目 我不能简单地从项目中删除过时的信息 但我确实想在选项无效时为用户提供视觉线索 我正在考虑对项目进行着色 可能是红色 来指示它们是否无效
  • wpf中的图像问题(图像不显示)

    我不明白为什么我无法在 WPF 中显示图像 也许我不小心修改了我的资源文件夹 这就是我没有显示的原因 所以我创建了一个新的 wpf 应用程序 我有这个 当我运行该程序时 我的图片显示为 为什么当我尝试在程序中执行相同的操作时 图像没有显示
  • 文件按文件名模式存在

    我在用 File Exists filepath 我想做的是将其替换为模式 因为文件名的第一部分发生了变化 例如 该文件可以是 01 peach xml 02 peach xml 03 peach xml 如何根据某种搜索模式检查文件是否存

随机推荐

  • 我应该在 ssh 公钥中使用我的个人电子邮件吗?

    阅读 Github 的生成 SSH 密钥 https help github com articles generating ssh keys 教程 我在第 2 步 生成新的 SSH 密钥 https help github com art
  • 为什么 python 模块可以在 shell 中工作,但不能在脚本中工作?

    我正在尝试制作两个程序 我想要一台打印我居住城市的当前天气 而我想要另一台从在线帐户获取数据并将其返回 对于这些脚本 我导入 yweather 模块和 requests 模块 当我将它们导入 shell 时没有问题 但是当我运行脚本时它显示
  • 代码顺序和性能

    我想找到哪个更快 结构与数组 因此 我编写了一段 GO 代码 其中将 4 个 int 值 1 2 3 和 4 写入结构体的成员 然后写入长度为 4 的数组 我试图找出写入所需的时间 Case1 首先 我将值写入结构体 然后写入数组 在这里我
  • 为什么顺风找不到我的动态类?

    所以我尝试根据对象数组动态加载类 div item name div 我检查了浏览器上的元素面板 类属性加载正确 但 css 没有 为什么会这样 任何帮助将不胜感激 Tailwind 生成一个仅包含项目中使用的类的 CSS 文件 它无法识别
  • 使用 pecl oauth 为 LTI Outcomes 服务构建主体签名的 oauth xml 请求

    我正在使用 pecl oAuth 库 是否可以构建一个如下所示的正文签名的 oauth 请求 POST http www imsglobal org developers BLTI service handle php HTTP 1 0 H
  • 真正最小的口齿不清

    要使一种语言成为图灵完备且是 lisp 变体 所需的最小原语集是什么 看起来像 car cdr 和一些流量控制以及 REPL 的东西就足够了 如果有这样的清单就好了 假设只有 3 种数据类型 整数 符号和列表 就像 picolisp 中一样
  • 在android studio中创建AVD时出错

    我是 android studio 的新手 我的问题是当我尝试创建 AVD 时它的显示 未知错误 有关详细信息 请参阅 idea log 我正在 Windows 8 上工作 删除目录 home android avd 中的所有文件和文件夹
  • 奇怪的 Python Selenium 按钮点击行为

    我试图点击的部分 ul class btns right li a href class expand all View All Cards a li ul 我想很简单 但我似乎错过了一些东西 问题现在在页面下方更新了一点 xpath 不是
  • Docker compose 将本地目录映射到 dockerfile 卷

    我正在使用 Apache MySql Docker compose 设置 这一切都很好 然而 由于这是本地开发 因此问题出现了 Web 容器指向本地文件夹 而我需要 Apache 拥有该文件夹的权限 Using RUN mkdir www
  • WordPress:WP_Query 如何应用自定义帖子类型的搜索条件

    我有一个自定义帖子类型 photo 并且需要使用各种条件搜索与标题或描述与搜索关键字匹配的照片 包含LIKE search term 以 开始LIKE search term 等等 我有以下查询 但这不会根据 search term 请指引
  • Cython nogil 与 ThreadPoolExecutor 没有提供加速

    我假设如果我使用 Cython 编写代码nogil指令 这确实会绕过 gil 我可以使用ThreadPoolExecutor使用多个核心 或者 更有可能的是 我在实施过程中搞砸了一些事情 但我似乎不知道是什么 我使用 Barnes Hut
  • 使用 React-leaflet version3 的传单地图上的自定义按钮

    我是 React typescript 的新传单学习者 想要在地图上创建自定义按钮 单击该按钮后 将出现一个弹出窗口 我看到了很多例子 但它们都是基于旧版本的 我也尝试创建自己的例子 但没有成功 该文档也没有提供太多帮助 即使是功能性自定义
  • 我应该为这个带有 websockets 的 web 应用程序使用什么解决方案。活动MQ?

    我目前正在开发一个网络应用程序 它需要一个 websocket 连接来接收来自服务器的事件通知 客户端被分成组 并且组中的所有客户端必须接收相同的事件通知 我认为 ActiveMQ 可能可以支持这种模型 为每组客户端使用不同的队列 使用 s
  • 将 Oracle 外连接转换为 SQL Server

    我在将此 Oracle SQL 转换为 SQL Server 时遇到问题 这是查询 SELECT CM ModuleID CM ModuleDescription CM ImageIndex CASE WHEN CMAC ClassID I
  • 使用 Android 意图共享图像

    我正在尝试通过这样的共享意图来共享图像 Intent sharingIntent new Intent android content Intent ACTION SEND sharingIntent setType image png s
  • 如何使用 Pandas 从一个文件读取多个数据集?

    我有一个文件 其中包含由行分隔的多组数据 它看起来像 country1 0 9 1 3 2 9 1 1 country2 4 1 3 1 0 2 我想使用 Pandas 将整个文件读入多个数据帧 其中每个数据帧对应一个国家 地区 有什么简单
  • 如何从BroadcastReceiver获取数据到Activity?

    我编写了 SMS 应用程序 并为其编写了 BroadcastReceiver 我想从 BroadcastReceiver 获取数据到我的 Activity 中 那么如何获取它 我的广播接收器代码如下 public class SmsRece
  • Rails - 根据用户选择动态设置 time_zone

    感谢您对我的新网站功能之一的帮助 这是关于动态时区 根据要求用户可以从一组预定义时区 例如 us zones 中进行选择 当用户选择区域时 整个站点应设置 更新为时区 然而 目前新的时区还没有更新到 Apache 中 并且时区的更新仅在服务
  • 如果 ID 为数字,Bootstrap 手风琴将无法工作

    将 Bootstrap 升级到 4 2 1 版本后出现问题 在这个版本中 当我使用id 12 in accordion它不起作用 在以前的版本中 它可以很好地使用id 12 有任何想法吗 div div class card div cla
  • wait 命令不会等待子进程完成 c cpp c++

    我正在尝试编写一个 C 程序 该程序创建一个子进程 运行一个命令并将输出通过管道返回到父进程正在运行的命令的输入 我让父级执行 wait NULL 或 wait void pid 命令 但它不等待 这是代码 include