进程-(4)

wait()、waitpid()函数

简介
1)当一个进程正常或异常终止时,内核就向其父进程发送SIGCHLD信号。父进程可以忽略该信号,或者提供一个该该信号的处理函数。默认情况下,系统会忽略该信号
2)如果父进程调用了wait或waitpid时
如果其子进程都还在运行,则阻塞
如果一个子进程已终止,正等待父进程获取其终止状态,则取得该子进程的终止状态立即返回
如果它没有任何子进程,则立即返回

两个函数的区别

在一个子进程终止前,wait使其调用者阻塞,而waitpid 很多选择
如果一个子进程已经终止,并且是僵死进程,wait会立即返回并取得该子进程的状态,否则阻塞。

wait()和waitpid()可以让父进程等待子进程的结束,效果:父进程阻塞,子进程运行,直到子进程结束。
wait()等待方式比较单一,waitpid()等待方式有更多的选择。

wait() 函数:

pid_t wait(int* status)
等待任意一个子进程结束,status 会存储结束子进程的信息(退出码,是否正常退出等),返回值是结束子进程的PID。会导致父进程一直阻塞,直到有一个子进程结束为止(包括僵尸子进程)。
也就是说wait()函数,参数是退出码,返回值是结束的子进程的pid;wait() 可以回收僵尸子进程;
宏函数:WIFEXITED(status)可以判断是否正常退出,如果正常退出返回真,而WEXITSTATUS(status)取退出码(exit(值))。

Waitpid() 函数

如果进程有几个子进程,那么要等待指定的进程终止,可使用waitpid
pid_t waitpid(pid_t pid,int* status,int option)
参数:pid参数
==-1,等待任意子进程,与wait等效
>0 等待指定子进程
==0 等待其组ID等于调用进程组ID的任一子进程
<-1 等待其组ID等于pid绝对值的任一子进程
option可以指定是否阻塞方式等待,WNOHANG就相当于非阻塞方式等待。
返回:阻塞方式:返回结束子进程的PID,失败返回-1 。
WNOHANG方式:返回结束子进程的PID,如果没有子进程结束,返回0,失败返回-1。

例子:wait() 函数的调用
#include <stdio.h>
#include <unistd.h>
#include <sys/wait.h>
#include <stdlib.h>

int main()
{
pid_t pid = fork();
if(pid == 0){//子进程分支
printf("子进程%d开始运行\n",getpid());
sleep(3);
printf("子进程结束运行\n");
exit(100); }
printf("父进程等待子进程的结束\n");
int status;
pid_t wpid = wait(&status);
printf("等待结束\n");
printf("wpid=%d\n",wpid);
if(WIFEXITED(status))
printf("子进程正常结束,退出码:%d\n",
WEXITSTATUS(status));
}

结果如下:
父进程等待子进程的结束
子进程20304开始运行
子进程结束运行
等待结束
wpid=20304
子进程正常结束,退出码:100

上面的结果表明:因为不知道父子进程,那个先开始,所以,在子进程中,需要sleep一下,让子进程等等;
然后,好查看父进程的效果;
而且,子进程有调用函数exit,则他会在调用函数处,会自动结束子进程;从而,后续只运行父进程,查看的更加清晰;

例子2:开始显示waitpid()的效果
#include <stdio.h>
#include <stdlib.h>
#include <sys/wait.h>
#include <unistd.h>

int main(){
pid_t pid1,pid2;
pid1 = fork();
if(pid1 > 0) pid2 = fork();//只有父进程能执行
if(pid1 == 0){ //子进程一分支
printf("子进程一%d开始运行\n",getpid());
sleep(3); printf("子进程一结束\n");
exit(100); }
if(pid2 == 0){//子进程二分支
printf("子进程二%d开始运行\n",getpid());
sleep(1); printf("子进程二结束\n");
exit(200); }
int status;
waitpid(pid1,&status,0);//阻塞等待
if(WIFEXITED(status)) printf("EXIT=%d\n",
WEXITSTATUS(status));//查vfork()手册并写测试代码
}

[[email protected] day07]# vi waitpid3.c
[[email protected] day07]# gcc waitpid3.c -o waitpid3
[[email protected] day07]# ./waitpid3
子进程一23175开始运行
子进程二23173开始运行
子进程二结束
子进程一结束
EXIT=100

例子4:
#include <stdio.h>
#include <stdlib.h>
#include <sys/wait.h>
#include <unistd.h>

int main(){
pid_t pid1,pid2;
pid1 = fork();
if(pid1 > 0) pid2 = fork();//只有父进程能执行
if(pid1 == 0){ //子进程一分支
printf("子进程一%d开始运行\n",getpid());
sleep(3); printf("子进程一结束\n");
exit(100); }
if(pid2 == 0){//子进程二分支
printf("子进程二%d开始运行\n",getpid());
sleep(1); printf("子进程二结束\n");
exit(200); }
int status;
waitpid(-1,&status,0);//阻塞等待
if(WIFEXITED(status)) printf("EXIT=%d\n",
WEXITSTATUS(status));//查vfork()手册并写测试代码
}

[[email protected] day07]# vi waitpid3.c
[[email protected] day07]# gcc waitpid3.c -o waitpid3
[[email protected] day07]# ./waitpid3
子进程一23175开始运行
子进程二23173开始运行
子进程二结束
EXIT=100
子进程一结束
说明如果没有指定waitpid,的pid参数,给以-1为参数,则会造成父进程接受到任意一个子进程结束的pid结束信息,就返回;

例子5:

#include <stdio.h>
#include <stdlib.h>
#include <sys/wait.h>
#include <unistd.h>

int main(){
pid_t pid1,pid2;
pid1 = fork();
if(pid1 > 0) pid2 = fork();//只有父进程能执行
if(pid1 == 0){ //子进程一分支
printf("子进程一%d开始运行\n",getpid());
sleep(3); printf("子进程一结束\n");
exit(100); }
if(pid2 == 0){//子进程二分支
printf("子进程二%d开始运行\n",getpid());
sleep(1); printf("子进程二结束\n");
exit(200); }
int status;
waitpid(-1,&status,WNOHANG);//阻塞等待
if(WIFEXITED(status)) printf("EXIT=%d\n",
WEXITSTATUS(status));//查vfork()手册并写测试代码
}

[[email protected] day07]# vi waitpid3.c
[[email protected] day07]# gcc waitpid3.c -o waitpid3
[[email protected] day07]# ./waitpid4
子进程一23175开始运行
EXIT=0
子进程二23173开始运行
子进程二结束
子进程一结束

如果waitpid() 的option 参数,使用WNOHANG 的时候,如果子进程没有立马返回,相应码信息,则直接过去,返回0;

时间: 2024-10-14 20:13:44

进程-(4)的相关文章

C#:多进程开发,控制进程数量

正在c#程序优化时,如果多线程效果不佳的情况下,也会使用多进程的方案,如下: System.Threading.Tasks.Task task=System.Threading.Tasks.Task.Factory.StartNew( (object mystate) => { Process process = Process.Start("AutoCollectMrMultipleProcess.exe", mystate.ToString()); process.WaitF

C# 远程服务器 安装、卸载 Windows 服务,读取远程注册表,关闭杀掉远程进程

这里安装windows服务我们用sc命令,这里需要远程服务器IP,服务名称.显示名称.描述以及执行文件,安装后需要验证服务是否安装成功,验证方法可以直接调用ServiceController来查询服务,也可以通过远程注册表来查找服务的执行文件:那么卸载文件我们也就用SC命令了,卸载后需要检测是否卸载成功,修改显示名称和描述也用sc命令.至于停止和启动Windows服务我们可以用sc命令也可以用ServiceController的API,当停止失败的时候我们会强制杀掉远程进程,在卸载windows

【转】linux下杀死进程(kill)的N种方法

转载一篇,最原始的出处已不可考,望见谅! 常规篇: 首先,用ps查看进程,方法如下: $ ps -ef --smx       1822     1  0 11:38 ?        00:00:49 gnome-terminalsmx       1823  1822  0 11:38 ?        00:00:00 gnome-pty-helpersmx       1824  1822  0 11:38 pts/0    00:00:02 bashsmx       1827    

os -- 进程的控制

os -- 进程的控制 新建 模板 小书匠 参考 <计算机操作系统>(第四版) 汤小丹等编著 概念引入 进程控制 进程控制是最基本的功能,负责创建进程.结束进程等功能,一般由 OS 内核中的原语来实现 原语 所谓原语,就是由若干条指令组成的,用于完成一定功能的一个过程,算是不可分割的.最基本的操作 Note 接下来原语基本用于所有的操作 操作系统内核 操作系统将一些常用或者运行频率较高的模块(如时钟管理.进程调度等)常驻内存,这些就被称为 OS 内核 两大功能 支撑功能 中断处理 时钟管理 原

linux进程管理

进程管理 进程 Process 某应用程序打开的进程 PID Process ID 类型: 用户空间进程 内核空间进程 静态查看进程的状态 # ps [[email protected] ~]# ps >>>>查看本终端的进程 PID TTY          TIME CMD 4206 pts/0    00:00:00 bash 4378 pts/0    00:00:00 ps 选项的使用方式: BSD风格:选项没有横线- ps aux SysV风格:选项需要带有横线-  

linux基本命令整理(三):进程和vim

linux基本命令整理(三) -----------进程和vim 一.进程 1.查看进程 ps:将某个时间点的程序运行的状况截取下来 a:所有的进程 x:后台进程 u:有效的使用者相关的进程(常用组合aux) -IA:也能观察系统所有的数据 axjf:连同部分的程序树状态 -I:今查看和自己bash相关的程序 top:动态的观察进程的变化 -d:后面接描述,就是整个页面刷新的时间:默认是5秒 -b:以批次的方式执行top -n:与-b搭配使用,意义是需要进行几次top的输出结果 如:top -b

内存池、进程池、线程池

首先介绍一个概念"池化技术 ".池化技术 一言以蔽之就是:提前保存大量的资源,以备不时之需以及重复使用. 池化技术应用广泛,如内存池,线程池,连接池等等.内存池相关的内容,建议看看Apache.Nginx等开源web服务器的内存池实现. 起因:由于在实际应用当中,分配内存.创建进程.线程都会设计到一些系统调用,系统调用需要导致程序从用户态切换到内核态,是非常耗时的操作.           因此,当程序中需要频繁的进行内存申请释放,进程.线程创建销毁等操作时,通常会使用内存池.进程池.

Linux进程的睡眠和唤醒

1   Linux进程的睡眠和唤醒 在Linux中,仅等待CPU时间的进程称为就绪进程,它们被放置在一个运行队列中,一个就绪进程的状态标志位为TASK_RUNNING.一旦一个运行中的进程时间片用完, Linux内核的调度器会剥夺这个进程对CPU的控制权,并且从运行队列中选择一个合适的进程投入运行. 当然,一个进程也可以主动释放CPU的控制权.函数schedule()是一个调度函数,它可以被一个进程主动调用,从而调度其它进程占用CPU.一旦这个主动放弃CPU的进程被重新调度占用CPU,那么它将从

C#杀掉进程的方法

1 private static string CmdName = "cmd"; 2 /// <summary> 3 /// 关闭进程 4 /// </summary> 5 /// <param name="processName">进程名</param> 6 private void KillProcess(string processName) 7 { 8 Process[] myproc = Process.Ge

Linux进程管理与调度-之-目录导航【转】

转自:http://blog.csdn.net/gatieme/article/details/51456569 版权声明:本文为博主原创文章 && 转载请著名出处 @ http://blog.csdn.net/gatieme 目录(?)[-] 项目链接 进程的描述 进程的创建 进程的加载与运行 进程的退出 进程的调度 调度普通进程-完全公平调度器CFS 日期 内核版本 架构 作者 GitHub CSDN 2016-07-21 Linux-4.6 X86 & arm gatieme