为什么信号处理程序中的 waitpid 需要循环?

2024-02-29

我在一本电子书中读到, waitpid(-1, &status, WNOHANG) 应该放在 while 循环下,这样如果多个子进程同时退出,它们都会被收获。

我尝试了这个概念,同时创建和终止 2 个子进程,并通过 waitpid 不使用循环来获取它。并且全部都被收获了。

问题是,是否有必要将waitpid置于循环中?

#include<stdio.h>
#include<sys/wait.h>
#include<signal.h>

int func(int pid)
{
  if(pid < 0)
    return 0;
  func(pid - 1);
}

void sighand(int sig)
{
  int i=45;
  int stat, pid;
  printf("Signal caught\n");
  //while( (
  pid = waitpid(-1, &stat, WNOHANG);
  //) > 0){
  printf("Reaped process %d----%d\n", pid, stat);
  func(pid);
}

int main()
{
  int i;
  signal(SIGCHLD, sighand);
  pid_t child_id;

  if( (child_id=fork()) == 0 )  //child process
  {
    printf("Child  ID %d\n",getpid());
    printf("child exiting ...\n");
  }
  else
  {
    if( (child_id=fork()) == 0 ) //child process
    {
      printf("Child ID %d\n",getpid());
      printf("child exiting ...\n");
    }
   else
    {
      printf("------------Parent with  ID %d \n",getpid());
      printf("parent exiting ....\n");
      sleep(10);
      sleep(10);
    }
  }
}

Yes.

好的,我会详细说明。

每次调用 waitpid 都会获得一个且只有一个孩子。由于您将调用放入信号处理程序中,因此无法保证第二个子处理程序会在您完成执行第一个信号处理程序之前退出。对于两个进程来说,这是可以的(待处理信号将在您完成时处理),但对于更多进程,可能是两个子进程将完成,而您仍在处理另一个进程。由于信号没有排队,您将错过通知。

如果发生这种情况,你将无法收获所有的孩子。为了避免这个问题,引入了循环建议。如果您想看到这种情况发生,请尝试与更多的孩子一起进行测试。你跑得越多,你就越有可能发现问题。

抛开这个问题,我们来谈谈其他一些问题。

首先,您的信号处理程序调用printf。这是一个主要的禁忌。很少有函数是信号处理程序安全的,并且printf绝对不是一个。您可以尝试使信号处理程序更安全,但更明智的方法是放入仅设置标志的信号处理程序,然后执行实际的操作wait调用主程序的流程。

由于您的主要流程通常是调用 select/epoll,因此请确保查找pselect and epoll_pwait,并了解它们的作用以及为什么需要它们。

更好(但特定于 Linux),请查找signalfd。您可能根本不需要信号处理程序。

编辑添加: 该循环不会改变两个信号传递合并到一个处理程序调用中的事实。它所做的就是这个调用处理所有待处理的事件。

当然,一旦出现这种情况,你must use WNOHANG。导致信号合并的相同工件也可能导致您处理尚未传递信号的事件。

如果发生这种情况,那么一旦您的第一个信号处理程序存在,它将再次被调用。然而,这一次,不会有待处理的事件(因为事件已经被循环提取)。如果您不指定WNOHANG, your wait阻塞,程序将无限期地卡住。

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

为什么信号处理程序中的 waitpid 需要循环? 的相关文章

  • 分段错误(核心转储)错误

    我的程序编译罚款 但在输入文件时出现 分段错误 核心转储 错误 我没有正确处理 ostream 吗 include
  • 将字节数组转换为托管结构

    更新 这个问题的答案帮助我编写了开源项目GitHub 上的 AlicanC 现代战争 2 工具 https github com AlicanC AlicanC s Modern Warfare 2 Tool 你可以看到我是如何阅读这些数据
  • System.IO.IOException:由于意外>数据包格式,握手失败?

    有谁知道这意味着什么 System Net WebException 底层连接已关闭 发送时发生意外错误 gt System IO IOException 由于意外 握手失败 数据包格式 在 System Net Security SslS
  • ASP.NET Core 与现有的 IoC 容器和环境?

    我想运行ASP NET 核心网络堆栈以及MVC在已托管现有应用程序的 Windows 服务环境中 以便为其提供前端 该应用程序使用 Autofac 来处理 DI 问题 这很好 因为它已经有一个扩展Microsoft Extensions D
  • 为什么Apache MPM prefork.c 使用互斥体来保护accept()?

    我坐下来读书Apache 的 MPM prefork c http code metager de source xref apache httpd server mpm prefork prefork c这段代码使用了一个名为accept
  • 在 C++ 中将成对向量转换为两个独立向量的最快方法

    假设我有一个vector of pair
  • 在 C# Winforms 应用程序中嵌入 Windows XP 主题

    我有一个旧版 C Windows 窗体应用程序 其布局是根据 Windows XP 默认主题设计的 由于需要将其作为 Citrix 应用程序进行分发 该应用程序现在看起来像经典主题应用程序 因为 Citrix 不鼓励使用主题系统服务 所以
  • 劫持系统调用

    我正在编写一个内核模块 我需要劫持 包装一些系统调用 我正在暴力破解 sys call table 地址 并使用 cr0 来禁用 启用页面保护 到目前为止一切顺利 一旦完成 我将公开整个代码 因此如果有人愿意 我可以更新这个问题 无论如何
  • HttpWebRequest vs Webclient(特殊场景)

    我知道这个问题之前已经回答过thread https stackoverflow com questions 1694388 webclient vs httpwebrequest httpwebresponse 但我似乎找不到详细信息 在
  • 两种类型的回发事件

    1 我发现了两篇文章 每篇文章对两种类型的回发事件的分类都略有不同 一位资源说两种类型的回发事件是Changed事件 其中控件实现 IPostbackDataHandler 当数据在回发之间更改时触发 然后Raised事件 其中控件实现 I
  • 从 Code::Blocks 运行程序时出现空白控制台窗口 [重复]

    这个问题在这里已经有答案了 当我尝试在 Code Blocks 中构建并运行新程序时 控制台窗口弹出空白 我必须单击退出按钮才能停止它 它对我尝试过的任何新项目 包括 Hello world 都执行此操作 奇怪的是 它对于我拥有的任何旧项目
  • libxml2 xmlChar * 到 std::wstring

    libxml2似乎将所有字符串存储在 UTF 8 中 如xmlChar xmlChar This is a basic byte in an UTF 8 encoded string It s unsigned allowing to pi
  • C# 中的常量和只读? [复制]

    这个问题在这里已经有答案了 可能的重复 const 和 readonly 之间有什么区别 https stackoverflow com questions 55984 what is the difference between cons
  • asp.net网格分页的SQL查询

    我在用iBatis and SQLServer 使用偏移量和限制进行分页查询的最佳方法是什么 也许我添加该列ROW NUMBER OVER ORDER BY Id AS RowNum 但这只会阻止简单查询的数据访问 在某些情况下 我使用选择
  • 在 C++17 中使用 成员的链接错误

    我在 Ubuntu 16 04 上使用 gcc 7 2 并且需要使用 C 17 中的新文件系统库 尽管确实有一个名为experimental filesystem的库 但我无法使用它的任何成员 例如 当我尝试编译此文件时 include
  • C语言声明数组没有初始大小

    编写一个程序来操纵温度详细信息 如下所示 输入要计算的天数 主功能 输入摄氏度温度 输入功能 将温度从摄氏度转换为华氏度 独立功能 查找华氏度的平均温度 我怎样才能在没有数组初始大小的情况下制作这个程序 include
  • 受限 AppDomain 中的代码访问安全异常

    Goal 我需要在权限非常有限的 AppDomain 中运行一些代码 它不应该访问任何花哨或不安全的内容 except对于我在其他地方定义的一些辅助方法 我做了什么 我正在创建一个具有所需基本权限的沙箱 AppDomain 并创建一个运行代
  • 带有私有设置器的 EFCore Base 实体模型属性 - 迁移奇怪的行为

    实体模型继承的类内的私有设置器似乎会导致 EFCore 迁移出现奇怪的问题 考虑以下示例 其中有多个类 Bar and Baz 继承自Foo 跑步时Add Migration多次命令 添加 删除private修饰符 生成的模式在多个方面都是
  • 服务器响应 PASV 命令返回的地址与建立 FTP 连接的地址不同

    System Net WebException 服务器响应 PASV 命令返回的地址与建立 FTP 连接的地址不同 在 System Net FtpWebRequest CheckError 在 System Net FtpWebReque
  • 如何使用 C# 以低分辨率形式提供高分辨率图像

    尝试使用 300dpi tif 图像在网络上显示 目前 当用户上传图像时 我正在动态创建缩略图 如果创建的页面引用宽度为 500x500px 的高分辨率图像 我可以使用相同的功能即时转换为 gif jpg 吗 将创建的 jpg 的即将分辨率

随机推荐

  • NuxtJS 上的 ESLint 和 Prettier 冲突

    当我创建一个新的 Nuxt js 项目时 我遇到了 ESLint 和 Prettier 的一个非常令人筋疲力尽的问题 如果我节省这个 vue文件中 Prettier 尝试修复它 但 ESLint 阻止它这样做 所以 我无法删除这方面的错误
  • 拖动进入时突出显示按钮

    刚刚开始探索iOS SDK 我有一些按钮 需要突出显示它们 触摸一次然后拖动 据我了解 当您单击按钮然后拖动到外部然后再次拖动到内部时 会触发 TouchDragEnter 事件 当您单击按钮外部然后拖动到内部时 是否会触发任何事件 亚历山
  • 数据注释、IDataErrorInfo 和 MVVM

    我正在尝试找到验证 MVVM 中数据的最佳方法 目前 我正在尝试使用 MVVM 模式将 IDataErrorInfo 与数据注释结合使用 然而 似乎没有任何作用 我不确定我可能做错了什么 我有这样的东西 Model public class
  • 使用 numpy/scipy 的快速 B 样条算法

    我需要在 python 中计算 bspline 曲线 我研究了 scipy interpolate splprep 和其他一些 scipy 模块 但找不到任何可以轻松满足我需要的东西 所以我在下面编写了自己的模块 代码运行良好 但速度很慢
  • 如何保护 web.config 中存储的密码的安全?

    我在 web config 文件中添加了以下设置 以启动对外部系统的 API 调用 因此 我存储 API URL 用户名 密码 如下所示
  • 包含 MySQL 查询结果中未找到的值

    我有以下 MySQL 表 tbl pet owners id name pet city date adopted 1 jane cat Boston 2017 07 11 2 jane dog Boston 2017 07 11 3 ja
  • cygwin中如何杀死进程?

    您好 我有以下无法杀死的进程 我在 windows xp 32 位中运行 cygwin 我尝试发出以下命令 bin kill f 4760 bin kill 9 5000 kill 9 5000 kill 5000 当我写 bin kill
  • 如何在 .net 中获取可用的 wifi AP 及其信号强度?

    有没有办法使用 NET 访问所有 WiFi 接入点及其各自的 RSSI 值 如果我可以在不使用非托管代码的情况下完成它 那就太好了 或者如果它可以在 Mono 和 NET 中工作 那就更好了 如果可能的话 我将不胜感激代码示例 谢谢 以下是
  • 使用隐藏代码的 nbextensions 时查找并转到文本

    这是来自的重复this https stackoverflow com questions 530245473年前的问题 目前还没有令人满意的解决方案 问题是在使用 nbextensions 时 在 Jupyter Notebook 的所有
  • 虚拟机上奇怪的程序延迟行为

    我编写了一个程序来读取 256KB 数组以获得 1 毫秒的延迟 该程序非常简单并附带 然而 当我在Xen上的VM上运行它时 我发现延迟不稳定 它具有以下模式 时间单位是ms totalCycle CyclePerLine totalms 2
  • 使用 MySQLi 插入 NULL 而不是空值

    我有一个带有一些可选字段的表单 在数据库中 这些字段设置为接受 NULL 如果某些字段为空 下面的代码将引发错误 您能帮忙看看避免这种情况的最佳方法是什么吗 我想到的唯一解决方案是将变量设置为 if isempty query INSERT
  • 从无符号整数中减去有符号整数[重复]

    这个问题在这里已经有答案了 unsigned int value 1860 int data 1300 if data value gt 0 printf Why it is printing this 输出 为什么打印这个 我不明白为什么
  • linux gcc 链接器与 C 程序的问题

    我正在尝试编译一个包含 c 文件标头的 C 程序 但只有 1 个 c 文件真正使用了头文件中定义的变量 这是一些会产生链接器问题的示例代码 我试图让我的头文件包含 2 使用的全局变量 不同的 c 文件 任何类型的帮助将不胜感激 谢谢 tmp
  • directX 创建交换链

    在我的书中 我编写了创建交换链的代码 IDXGIDevice dxgiDevice 0 mD3dDevice gt QueryInterface uuidof IDXGIDevice void dxgiDevice IDXGIAdapter
  • modelBuilder.IncludeMetadataInDatabase 在 EF CTP5 中的位置在哪里?

    使用 CTP4 我曾经能够执行以下操作 如由 ptrandem 建议 https stackoverflow com questions 3600672 entity framework ctp4 code first how to tur
  • Google Cloud Run 屏蔽授权标头中的承载令牌

    Cloud Run 的 Google 文档指出 您可以 从授权标头中提取令牌 文档在这里 https cloud google com run docs authenticating end users getting user profi
  • 字符串数组中的随机元素[关闭]

    很难说出这里问的是什么 这个问题是含糊的 模糊的 不完整的 过于宽泛的或修辞性的 无法以目前的形式得到合理的回答 如需帮助澄清此问题以便重新打开 访问帮助中心 help reopen questions 我有一个字符串数组 String f
  • Heroku 上的 .Net Core 和 Docker

    Context 我正在尝试部署一个ASPNET核心示例应用程序上Heroku https heroku com 与 docker 但不工作 repo https github com mykeels sample web api https
  • 无法通过在 Apache Beam 中创建模板来按所需顺序运行多个管道

    我有两个独立的管道 分别为 P1 和 P2 根据我的要求 我只需要在 P1 完全完成执行后才运行 P2 我需要通过一个模板完成整个操作 基本上 模板在找到 run 方式 即 p1 run 时就被创建 所以我可以看到 我需要使用两个不同的模板
  • 为什么信号处理程序中的 waitpid 需要循环?

    我在一本电子书中读到 waitpid 1 status WNOHANG 应该放在 while 循环下 这样如果多个子进程同时退出 它们都会被收获 我尝试了这个概念 同时创建和终止 2 个子进程 并通过 waitpid 不使用循环来获取它 并