网络编程(32)—— linux中销毁僵尸进程的四种方法

2023-11-01

一、wait函数



函数原型:
pid_t wait(int *status);
描述:
wait可以回收任意一个僵尸进程,只要系统中存在僵尸进程,调用一次wait,就会回收一个僵尸进程。
参数说明:
  status - 当子进程结束之后,其进入僵尸进程状态。其状态变化信息被操作系统放置在内存中某一处位置,而status就是这处位置的指针,通过调用wait函数可以获取这部分位置的数据。
获取到数据之后,通过一系列宏可以获取目前操作系统的状态。如:
WIFEXITED(*status)可以判断该进程是否正常结束(main函数通过return或者exit结束),若正常结束返回true,否则返回false。
WEXITSTATUS(*status)用来获取进程正常结束时main函数的返回值,前提是WIFEXITED(status)返回true。
返回值:
返回被结束僵尸状态进程的进程ID。
举例:
int main()
{
	pid_t pid;
	int status;
	pid=fork();
	if(pid==0)
	{
		exit(10);
	}
	else
	{
		pid = wait(&status);
		if(WIFEXITED(status))
		{
			printf("process %d exited,return value = %d\n",pid,WEXITSTATUS(status));
		}
	}
	return 0;
}


缺点:
wait()函数为阻塞函数,也就是说如果操作系统中无僵尸进程的话,程序会一直在wait()处等待,直到出现僵尸进程。


二、waitpid函数



函数原型:
pid_t waitpid(pid_t pid, int *status, int options);
描述:
waitpid()也是用来回收一个僵尸进程,与wait()不同的是,它是非阻塞函数,可以通过设置pid参数回收指定进程ID的僵尸进程,也可以指定回收任意僵尸进程。
参数说明:
status,和wait()函数相同。
pid,指定要回收进程的进程ID,若设为-1,则默认回收任意一个僵尸进程。
options,设置选项,一般情况下设置成WNOHANG,表示不阻塞。
返回值
若存在僵尸进程,返回被结束僵尸状态进程的进程ID;若不存在僵尸进程返回0;若发生错误,返回-1.
举例:
int main()
{
	pid_t pid;
	int status;
	pid=fork();
	if(pid==0)
	{
		sleep(10);
		exit(10);
	}
	else
	{
		while((pid=waitpid(-1,&status,WNOHANG))==0)
		{
			puts("wating ...");
			sleep(2);
		}
		if(WIFEXITED(status))
		{
			printf("process %d exited,return value = %d\n",pid,WEXITSTATUS(status));
		}
	}
	return 0;
}


缺点:
虽然waitpid()不是阻塞函数,但是使用时需要在循环中使用,只有在回收完僵尸进程后才会执行循环之后的代码。


三 signal函数



函数原型:
sighandler_t signal(int signum, sighandler_t handler);
描述:
系统级别的api,向操作系统注册信号和信号处理函数,当操作系统捕获到注册的信号时会调用该信号处理函数。
参数:
signum,向操作系统注册的信号,子进程结束的信号是SIGCHLD。
handler,信号的处理函数,函数原型一般是void handler(int sig)的形式,函数的参数为操作系统捕获的信号,函数的返回值是void
返回值:
返回之前注册的处理该信号的信号处理函数的函数指针。
举例:
void sig_handling(int sig)
{
	int status;
	pid_t pid;
	if(sig==SIGCHLD)
	{
		pid = waitpid(-1,&status,WNOHANG);
		if(WIFEXITED(status))
		{
			printf("process %d exited,return value=%d\n",pid,WEXITSTATUS(status));
		}
	}
}


int main()
{
	pid_t pid;
	signal(SIGCHLD,sig_handling);
	pid=fork();
	if(pid==0)
	{
		exit(11);
	}
	else
	{
		sleep(10000);
	}
	return 0;
}


  请注意:
  1、在信号处理函数sig_handling中,也需要用waitpid()来回收僵尸进程,也就是说signal只是一个注册信号的作用,其本身并没有回收僵尸进程的功能。
  2、一旦用signal注册了信号和信号处理函数,一旦发生该信号,会结束进程的sleep()状态,也就是说在父进程的sleep(10000);将会被打断,不会真的睡10000秒。
 

四 sigaction函数



函数原型:
int sigaction(int signum, const struct sigaction *act,
                     struct sigaction *oldact);
描述:
signum,和signal一样,表示需要注册的信号。
act,sigaction类型的指针,sigaction类型的定义如下:

struct sigaction {
               void     (*sa_handler)(int);
               void     (*sa_sigaction)(int, siginfo_t *, void *);
               sigset_t   sa_mask;
               int        sa_flags;
               void     (*sa_restorer)(void);
           };
  我们进行使用时,只需填写其sa_handler、sa_mask、sa_flags三个成员,sa_handler为信号处理函数,sa_mask使用sigemptyset()函数进行置空,sa_flags直接赋为0。
  oldact,之前注册的  sigaction 类型的指针
返回值:
  成功返回0,失败返回-1
举例:
void sig_handling(int sig)
{
	int status;
	pid_t pid;
	if(sig==SIGCHLD)
	{
		pid = waitpid(-1,&status,WNOHANG);
		if(WIFEXITED(status))
		{
			printf("process %d exited,return value=%d\n",pid,WEXITSTATUS(status));
		}
	}
}


int main()
{
	pid_t pid;
	struct sigaction act;
	act.sa_handler=sig_handling;
	sigemptyset(&act.sa_mask);
	act.sa_flags=0;
	sigaction(SIGCHLD,&act,0);
	pid=fork();
	if(pid==0)
	{
		exit(11);
	}
	else
	{
		sleep(10000);
	}
	return 0;
}


  与signal相比,sigaction函数虽然比较繁琐,但是他的长处在于linux系统多版本的兼容性,而部分版本linux是不支持signal函数的,因此在实际的使用中sigaction的使用范围更广。

Github位置:
https://github.com/HymanLiuTS/NetDevelopment
克隆本项目:
Git clone git@github.com:HymanLiuTS/NetDevelopment.git
获取本文源代码:
git checkout NL32

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

网络编程(32)—— linux中销毁僵尸进程的四种方法 的相关文章

  • 在方法内部等待,直到捕获事件

    我在 C 中的一个方法上遇到了这个问题 我创建了一个从 dll 中调用函数的方法 其名为Phone GetLampMode Now Phone GetLampMode不返回任何东西 数据在事件中返回 onGetLampModeRespons
  • 等待函数完成执行并使用结​​果

    这是场景 我有一个活动 A 它有一个按钮和文本视图 我有另一个类 B 其中包含执行各种功能的方法 创建类 B 的实例后 当单击按钮时 会从 A 调用它的公共方法之一 该方法需要一段时间来执行 它调用类中另一个耗时的私有方法 并返回类 B 的
  • 如何创建javascript延迟函数[重复]

    这个问题在这里已经有答案了 我有一个 javascript 文件 在几个地方我想添加一个小的延迟 这样脚本就会到达该点 等待 3 秒 然后继续执行其余的代码 我想到的最好方法是创建一个函数 我可以从脚本中的任何位置调用该函数 functio
  • C# 的 ExpectedCondition 方法 attributeContains

    我试图使用 attributeContains 方法 但在使用 C 时没有可用的方法 https seleniumhq github io selenium docs api java org openqa selenium support
  • 在 C++ 中使用 istringstream

    我有一些代码利用 fork execlp 和 wait 来创建两个进程 目标是能够重复打印提示并让用户输入最多包含 4 个参数 选项的命令 int main string command argument istringstream iss
  • 等待所有线程完成java中的工作

    我正在编写一个具有 5 个线程的应用程序 这些线程同时从 Web 获取一些信息并填充缓冲区类中的 5 个不同字段 当所有线程完成其工作时 我需要验证缓冲区数据并将其存储在数据库中 我该如何做到这一点 当所有线程完成工作时收到警报 我采取的方
  • 等待用户输入 C# 控制台应用程序的设置时间

    对于控制台应用程序 我需要知道在继续应用程序的 自动运行 部分之前 如何等待用户输入一个或一组按键设定的时间 大约 10 秒 这让我很困扰 因为我不太清楚计时器是如何工作的 或者 threading sleep 我应该使用什么 一整天都在谷
  • Java - 等待和notifyAll

    当你对一个没有等待的对象调用notifyAll方法时会发生什么 应该有例外还是正常情况 正如您在这里所看到的 对未等待的对象调用notifyAll 不会产生任何效果
  • 使用命令行等待 kubernetes 作业在失败/成功时完成

    等待 kubernetes 作业完成的最佳方式是什么 我注意到很多使用建议 kubectl wait for condition complete job myjob 但我认为只有工作成功才有效 如果失败 我必须做类似的事情 kubectl
  • Perl后台进程

    我正在尝试在 perl 中运行后台进程 我创建了一个子进程 用于调用另一个 perl 脚本 我想与这个子进程并行运行几行代码 子进程完成后 我想打印一行代码 主要脚本 usr bin perl 1 print before the chil
  • 等待信号,然后继续执行

    我正在尝试制作一个程序suspends它的执行直到信号到达 然后 信号到达后我只想我的代码从原来的地方继续执行 我不希望它执行函数处理程序或任何其他内容 有没有一种简单的方法可以做到这一点 我已经奋斗了一周左右 到处阅读 但没有设法获得完全
  • 等待用户的所有作业完成,然后再将后续作业提交到 PBS 集群

    我正在尝试调整一些 bash 脚本以使它们在 pbs questions tagged pbs 簇 各个任务由由主脚本启动的多个脚本执行 到目前为止 这个主脚本在后台启动多个脚本 通过附加 使它们在一台多核机器上并行运行 我想用以下方式替换
  • 如何在非线程对象上调用 wait() 和 notification() 方法?

    怎样才能wait and notify 在非线程的对象上调用方法 这确实没有意义 不是吗 不过 这肯定是有意义的 因为这两种方法可用于所有 Java 对象 有人可以提供解释吗 我无法理解如何使用线程之间进行通信wait and notify
  • JavaScript、node.js 在继续之前等待 socket.on 响应

    我需要从客户端的服务器获取信息 所以在服务器端 当客户端第一次连接时我得到了这个 socket on adduser function username misc code where i set num player and whatno
  • fork()返回0,但是子进程getpid()!=0。为什么?

    这是测试 fork 系统调用的 C 代码 include
  • Android 在 AlertDialog 中等待用户输入以继续

    我看到这里讨论了这个主题 但似乎不明白如何继续 In my onCreate我有代码检查它是否是应用程序的第一次运行firstRun getPref getBoolean firstRun true 如果是第一次运行该应用程序 则会显示一个
  • 如何冻结一个线程并从另一个线程通知它?

    我需要暂停 Rust 中的当前线程并从另一个线程通知它 在Java中我会写 synchronized myThread myThread wait 并从第二个线程 恢复主线程 synchronized myThread myThread n
  • 监视器应该等待什么对象?

    使用 Monitor Wait object obj 时 应该对 obj 使用什么 在这个article http www yoda arachsys com csharp threads 我正在阅读 NET 中的多线程 作者实例化了一个新
  • 等待(长超时)和加入(长毫秒)之间的区别?

    当线程 1 在线程 2 上调用 wait 和 join 方法时 线程 1 会等待线程 2 一段时间或直到线程 2 完成 如果我们使用这些方法的重载版本 即 wait long timeout 和 join long millis 那么 在
  • signal(SIGCHLD, SIG_DFL); 是什么意思?意思是?

    我不处理SIGCHLD在我的代码中 我的进程仍然在终止后立即被删除 我希望它成为僵尸进程 如果我设置SIGCHLD to SIG DFL那么 它会起作用吗 我该如何设置SIGCHLD to SIG DFL 我希望进程成为僵尸 这样我就可以在

随机推荐

  • opencv(十三)--边缘检测和梯度

    目标 图像梯度 图像边界等 使用到的函数有 cv2 Sobel cv2 Schar cv2 Laplacian 等 原理 梯度简单来说就是求导 OpenCV 提供了三种不同的梯度滤波器 或者说高通滤波器 Sobel Scharr 和Lapl
  • Qt 之 QVideoFrame转换为QImage

    提示 文章写完后 目录可以自动生成 如何生成可参考右边的帮助文档 文章目录 前言 方法一 最简单 方法二 依赖opencv 方法三 qt5 15版本 前言 在qt框架下 实现相机预览的几种方式在qt相机预览已经描述过了 在该文章的几种方式中
  • 二叉搜索树(数组实现)

    内容 建立二叉搜索树 bool buildtree int k tree k value a index int cur 0 if index a size return true while 1 if a index lt tree cu
  • 正整数序列的数

    正整数序列的数 正整数序列的数量 问题描述 小明想知道 满足以下条件的正整数序列的数量 1 第一项为 n 2 第二项不超过 n 3 从第三项开始 每一项小于前两项的差的绝对值 请计算 对于给定的 n 有多少种满足条件的序列 输入格式 输入一
  • Qt使用gSoap实现webservice服务端和客户端

    文章目录 gSoap工具介绍 1 下载 2 Hello world 开始使用SOAP api 2 1 新建文件夹 2 2 新建服务接口头文件 hello h 2 3 使用 soapcpp2 exe 2 4 拷贝源代码库文件 2 5 Qt 服
  • 第二次作业:微信案例分析

    2 1 介绍产品相关信息 你选择的产品是 微信 为什么选择该产品作为分析 微信是一款全方位的手机通讯应用 帮助我们轻松连接全球好友 微信可以通过SMS MMS网络发送短信 进行视频聊天 与好友一起玩游戏 以及分享自己的生活到朋友圈 让我们感
  • Stable Diffusion 个人推荐的各种模型及设置参数、扩展应用等合集(不断更新中)

    本文主要是把平时使用的模型及其参数进行推荐和整理 相关 安装及其问题解决参考 Windows安装Stable Diffusion WebUI及问题解决记录 运行使用时问题 Windows使用Stable Diffusion时遇到的各种问题整
  • Stack,ArrayDeque,LinkedList的区别

    这段时间把疯狂JAVA再看了一遍 发现Stack ArrayDeque LinkedList都可以作为栈使用 所以就稍微从性能以及实现的细节对比这三者的区别 类继承树 由继承树看出 三者都是Collection的间接实现类 ArrayDeq
  • js中数组删除对象的几种方式总结

    1 关键字删除 2 splice删除 3 特殊位置删除 一 关键字删除 关键字删除是通过js提供的关键字 delete手动删除数组的某一项 使用delete删除掉数组中的元素后 会把该下标出的值置为undefined 数组的长度不会变 ar
  • 一个案例说明高层属性形式化验证

    1 验证软件功能介绍 Beosin VaaS的业务逻辑验证软件 是一款用来检测智能合约上层业务逻辑漏洞的软件 基于合约的白皮书 软件利用形式化方法 首先对单个函数进行属性的描述 在对单个函数进行属性的验证并通过后 基于这些已验证属性 抽取出
  • 号传到服务器为空,URL 传+号到后台变空格问题解决方案

    今天在调试客户端向服务器传递参数时 参数中的 全部变成了空格 原因是URL中默认的将 号转义了 解决方法如下 方法一 修改客户端 将客户端带 的参数中的 全部替换为 2B 这样参数传到服务器端时就能得到 了 方法二 修改服务器端 将空格替换
  • 第六天作业

    include
  • VC++操作SQLserver动态库【含源码】,及动态库使用教程。

    VC 操作SQLserver动态库 含源码 动态库使用Demo程序演示 include
  • Unity Window触摸屏电脑和移动端Input触控,控制相机旋转缩放

    Unity Window触摸屏电脑和移动端Input触控 控制相机旋转缩放 原理就是获取手指滑动的偏移量 来计算 代码帖出来 using UnityEngine using System using System Collections p
  • Codeforces 670C Cinema

    题目链接 https codeforces com problemset problem 670 C include
  • numpy.array多维数组的切片操作总结

    numpy array多维数组的切片操作总结 一 常规介绍 1 一维数组切片 2 二维数组的切片 3 维数超过 3 的多维数组 可通过 来简化操作 4 numpy中对切片元素的操作会影响原数组本身 5 array和list的对比 6 boo
  • 100天精通Python(数据分析篇)——第61天:Pandas.to_datetime函数基础+代码实战(处理时间)

    文章目录 一 to datetime参数说明 代码实战 1 arg 2 errors 3 dayfirst 4 yearfirst 5 utc 6 format 7 exact 8 unit 9 infer datetime format
  • qt designer文本输入框_Qt为输入框提供提示信息

    当我们在使用一个陌生的软件时常常会感觉不知所措 因此在写软件的时候都要考虑增加一些信息来帮助使用者 比如说提供文字标签来告诉使用者某一块区域的作用是什么 又或者干脆用一块区域滚动显示一些提示 但这里要说的是一种很常见又有用的提示方式 在输入
  • 股指期货首次和二次开户条件

    不少投资者都问到 股指期货开户可以网上开通吗 还是要去柜台办理 由于股指期货具有双向交易以及T 0的特点 在大盘下跌的时候也可以对冲或者赚取盈利 深受投资者关注 今天期货开户网为您详细讲解自然人申请开通股指期货的详细流程 需提供的材料 准入
  • 网络编程(32)—— linux中销毁僵尸进程的四种方法

    一 wait函数 函数原型 pid t wait int status 描述 wait可以回收任意一个僵尸进程 只要系统中存在僵尸进程 调用一次wait 就会回收一个僵尸进程 参数说明 status 当子进程结束之后 其进入僵尸进程状态 其