进程等待详解

目录

一、进程等待的作用

二、进程等待的系统调用


一、进程等待的作用

        我们都知道,当子进程已经结束而父进程还在执行时,子进程会变成僵尸进程,造成内存泄漏等问题,如下:

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

int main()
{
  pid_t id = fork();
  if(id == 0)
  {
    int i = 5;
    while(i--)
    {
      printf("I am child, mypid is : %d\n", getpid());
      sleep(1);
    }
  }
  else  
  {
    while(1)
    {
      printf("I am father : %d\n", getpid());
      sleep(3);
    }
  }
  return 0;
}

        僵尸进程的危害十分严重,为了防止僵尸进程,及时地回收资源,我们可以采用进程等待的方式。

        进程等待有两点主要作用:                                                                                                                  1、父进程通过等待,回收子进程的资源。                                                                                        2、父进程通过等待,获取子进程的退出信息。 

二、进程等待的系统调用

        进程等待一般通过两个接口:wait() 以及 waitpid() 。

         1、wait() 的作用是等待任意一个子进程,默认为阻塞等待(等待时父进程阻塞,不能做其他事)。返回值:成功,返回等待的子进程的pid;失败,返回 -1。参数:输出型参数,返回的是对应子进程的退出信息。

        2、status:status有32位,我们只看低16位,0-6 低 7 位表示退出时收到的信号,7表示core dump 标识,8-15 也就是次低八位表示退出码。 

        3、waitpid()的作用也是等待,但它可以更细致的控制。参数:pid 的解释如下:

        我们一般用两个,pid == 0 表示等待任意一个子进程;pid > 0 表示等待进程ID==pid的进程。status是输出型参数,如解释 2。options 表示是否进行阻塞等待,0表示阻塞等待,1表示非阻塞等待,也可以用宏,WNOHANG表示非阻塞等待,WUNTRACED表示阻塞等待。

        返回值:在阻塞状态下,成功返回子进程pid,失败返回 -1;在非阻塞状态下,成功返回子进程pid,还在等返回0,失败返回 -1.

        测试代码:status次低八位是退出码,低七位是退出信号。

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

int main()
{
  pid_t id = fork();
  if (id == 0)
  {
    int i = 5;
    while (i--)
    {
      printf("I am child, mypid is : %d\n", getpid());
      sleep(1);
    }
    
    exit(30);//退出码
  }
  else
  {
    int status = 0;
    waitpid(id, &status, 0);
    printf("childprocess has exited, exit code : %d, exit signal : %d\n", (status>>8)&0xff, status & 0x7f);
    sleep(1);
  }
  return 0;
}

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

int main()
{
  pid_t id = fork();
  if (id == 0)
  {
    int i = 5;
    while (i--)
    {
      printf("I am child, mypid is : %d\n", getpid());
      sleep(1);
    }
    i /= 0;//退出信号:浮点错误 8 
    exit(30);
  }
  else
  {
    int status = 0;
    waitpid(id, &status, 0);
    printf("childprocess has exited, exit code : %d, exit signal : %d\n", (status>>8)&0xff, status & 0x7f);
    sleep(1);
  }
  return 0;
}

        我们也可以用宏来代替位操作来得到退出码和退出信号。

WEXITSTATUS(status) 表示退出码, WTERMSIG(status) 表示退出信号 (更多在man手册查看)

  • 13
    点赞
  • 12
    收藏
    觉得还不错? 一键收藏
  • 3
    评论
smss.exe  Session Manager 这个进程是不可以从任务管理器中关掉的。 这是一个会话管理子系统,负责启动用户会话。这个进程是通过系统进程初始化的并且对许多活动的, 包括已经正在运行的Winlogon,Win32(Csrss.exe)线程和设定的系统变量作出反映。在它启动这些进程后,它等待Winlogon或者Csrss结束。如果这些过程时正常的,系统就关掉了。如果发生了什么不可预料的事情,smss.exe就会让系统停止响应(就是挂起)。 spoolsv.exe 这个进程是不可以从任务管理器中关掉的。 缓冲(spooler)服务是管理缓冲池中的打印和传真作业。 service.exe 这个进程是不可以从任务管理器中关掉的。 大多数的系统核心模式进程是作为系统进程在运行。 包含很多系统服务 csrss.exe 子系统服务器进程 winlogon.exe 管理用户登录和推出的。而且winlogon在用户按下CTRL+ALT+DEL时就激活了,显示安全对话框。 winmgmt.exe win2000客户端管理的核心组件。当客户端应用程序连接或当管理程序需要他本身的服务时这个进程初始化 lsass.exe 这个进程是不可以从任务管理器中关掉的。 这是一个本地的安全授权服务,并且它会为使用winlogon服务的授权用户生成一个进程。这个进程是过使用授权的包,例如默认的msgina.dll来执行的。如果授权是成功的,lsass就会产生用户的进入令牌,令牌别使用启动初始的shell。其他的由用户初始化的进程会继承这个令牌的。 svchost.exe 包含很多系统服务 !!!->eventsystem,(SPOOLSV.EXE 将文件加载到内存中以便迟后打印等。)(附:Svchost.exe文件对那些从动态连接库中运行的服务来说是一个普通的主机进程名。Svhost.exe文件定位在系统的 %systemroot%\system32文件夹下。在启动的时候,Svchost.exe检查注册表中的位置来构建需要加载的服务列表。这就会使 多个Svchost.exe在同一时间运行。每个Svchost.exe的回话期间都包含一组服务, 以至于单独的服务必须依靠Svchost.exe怎样和在那里启动。这样就更加容易控制和查找错误. Svchost.exe 组是用下面的注册表值来识别。 HKEY_LOCAL_MACHINE\Software\Microsoft\Windows NT\CurrentVersion\Svchost 每个在这个键下的值代表一个独立的Svchost组,并且当你正在看活动的进程时,它显示作为一个单独的 例子。每个键值都是REG_MULTI_SZ类型的值而且包括运行在Svchost组内的服务。每个Svchost组都包含一个 或多个从注册表值中选取的服务名,这个服务的参数值包含了一个ServiceDLL值。 HKEY_LOCAL_MACHINE\System\CurrentControlSet\Services\Service explorer.exe 资源管理器 (internat.exe 托盘区的拼音图标) 就像任务条,桌面等等。这个进程并不是像你想象的那样是作为一个重要的进程运行在windows中,你可以从任务管理器中停掉它,或者重新启动。 通常不会对系统产生什么负面影响。 taskmagr.exe 这个进程就是任务管理器。 System Idle Process 这个进程是不可以从任务管理器中关掉的。 这个进程是作为单线程运行在每个处理器上,并在系统不处理其他线程的时候分派处理器的时间。 mstask.exe 这个进程是不可以从任务管理器中关掉的。 这是一个任务调度服务,负责用户事先决定在某一时间运行的任务的运行。 internat.exe 这个进程是可以从任务管理器中关掉的。 internat.exe在启动的时候开始运行。它加载由用户指定的不同的输入点。输入点是从注册表的这个位置HKEY_USERS\.DEFAULT\Keyboard Layout\Preload 加载内容的。 internat.exe 加载“EN”图标进入系统的图标区,允许使用者可以很容易的转换不同的输入点。 当进程停掉的时候,图标就会消失,但是输入点仍然可以通过控制面板来改变。 附加的系统进程(这些进程不是必要的,你可以根据需要通过服务管理器来增加或减少) regsvc.exe 允许远程注册表操作。(系统服务)->remoteregister winmgmt.exe 提供系统管理信息(系统服务):netinfo.exe->msftpsvc,w3svc,iisadmn tlntsvr.exe->tlnrsvr tftpd.exe 实现 TFTP Internet 标准。该标准不要求用户名和密码。远程安装服务的一部分。(系统服务) termsrv.exe ->termservice dns.exe 应答对域名系统(DNS)名称的查询和更新请求。(系统服务) 以下全是系统服务,并且很少会用到,如果你暂时用不着,应该关掉(对安全有害 ) tcpsvcs.exe  提供在 PXE 可远程启动客户计算机上远程安装 Windows 2000 Professional的能力。(系统服务)->simptcp 支持以下 TCP/IP 服务:Character Generator, Daytime, Discard, Echo, 以及 Quote of the Day。(系统服务) ismserv.exe  允许在 Windows Advanced Server 站点间发送和接收消息。(系统服务) ups.exe   管理连接到计算机的不间断电源(UPS)。(系统服务) wins.exe   为注册和解析 NetBIOS 型名称的 TCP/IP 客户提供 NetBIOS 名称服务。(系统服务) llssrv.exe   License Logging Service(system service) ntfrs.exe   在多个服务器间维护文件目录内容的文件同步。(系统服务) RsSub.exe   控制用来远程储存数据的媒体。(系统服务) locator.exe   管理 RPC 名称服务数据库.->rpclocator(区 RpcSs) lserver.exe   注册客户端许可证。(系统服务) dfssvc.exe   管理分布于局域网或广域网的逻辑卷。(系统服务) clipsrv.exe   支持"剪贴簿查看器",以便可以从远程剪贴簿查阅剪贴页面。(系统服务) msdtc.exe   并列事务,是分布于两个以上的数据库,消息队列,文件系统,或其它事务保护资源管理器。(系统服务) faxsvc.exe   帮助您发送和接收传真。(系统服务) cisvc.exe   Indexing Service(system service)!!! dmadmin.exe   磁盘管理请求的系统管理服务。(系统服务) mnmsrvc.exe   允许有权限的用户使用 NetMeeting 远程访问 Windows 桌面。(系统服务) netdde.exe   提供动态数据交换 (DDE) 的网络传输和安全特性。(系统服务) smlogsvc.exe   配置性能日志和警报。(系统服务) rsvp.exe   为依赖质量服务(QoS)的程序和控制应用程序提供网络信号和本地通信控制安装功能。(系统服务) RsEng.exe   协调用来储存不常用数据的服务和管理工具。(系统服务) RsFsa.exe   管理远程储存的文件的操作。(系统服务) grovel.exe   扫描零备份存储(SIS)卷上的重复文件,并且将重复文件指向一个数据存储点,以节省磁盘空间。(系统服务) SCardSvr.exe   对插入在计算机智能卡阅读器中的智能卡进行管理和访问控制。(系统服务) snmp.exe   包含代理程序可以监视网络设备的活动并且向网络控制台工作站汇报。(系统服务) snmptrap.exe   接收由本地或远程 SNMP 代理程序产生的陷阱消息,然后将消息传递到运行在这台计算机上 SNMP 管理程序。(系统服务) UtilMan.exe   从一个窗口中启动和配置辅助工具。(系统服务) msiexec.exe   依据 .MSI 文件中包含的命令来安装、修复以及删除软件。(系统服务) dllhost.exe   win2000的话,一般是组件com调用的需要dllhost装入内存。所以dllhost.exe负责asp3.0组件装入内存。iis启动后。有一个大约20mb左右的dllhost。如果你的web应用程序不能释放内存。如关掉数据库连接,释放对象。这个dllhost会越来越大。还有一个dllhost是。web客户端的。大约5mb左右。用多层构架的概念来理解,就是一个是dllhost存根,一个是dllhost骨干。com远程访问缺一不可。
进程间通信中,信号是一种非常重要的机制。它可以让一个进程向另一个进程发送一个异步通知,让接收进程执行特定的操作。 信号的基本概念是:当一个进程需要通知另一个进程发生了某个事件时,它可以向另一个进程发送一个信号。接收进程在接收到信号后,可以选择忽略该信号或者执行相应的处理程序。 信号可以由如下几种方式发送: 1. kill命令:可以使用kill命令向指定进程发送信号。 2. 信号函数:可以使用信号函数向指定进程发送信号。 3. 软件异常:当一个进程执行某些非法操作时,操作系统会向该进程发送一个信号。 常见的信号有: 1. SIGINT:中断进程。通常由Ctrl+C键触发。 2. SIGTERM:请求进程终止。通常由kill命令发送。 3. SIGKILL:强制进程终止。通常由kill命令发送。 4. SIGSTOP:暂停进程。通常由kill命令发送。 5. SIGCONT:恢复进程。通常由kill命令发送。 6. SIGUSR1和SIGUSR2:用户自定义信号。 在Linux系统中,可以使用kill命令向指定进程发送信号。例如: ``` kill -SIGINT pid ``` 这个命令会向指定pid的进程发送SIGINT信号,让该进程接收到信号后执行相应的处理程序。 在编写程序时,可以使用信号函数向指定进程发送信号。例如,下面的代码向指定进程发送SIGUSR1信号: ``` #include <signal.h> #include <unistd.h> int main() { int pid = 12345; // 指定进程的pid kill(pid, SIGUSR1); // 向指定进程发送SIGUSR1信号 return 0; } ``` 当接收进程接收到信号后,可以执行相应的处理程序。例如,下面的代码定义了一个信号处理程序,当接收到SIGUSR1信号时会执行该处理程序: ``` #include <signal.h> void handle_signal(int signum) { // 处理SIGUSR1信号 } int main() { signal(SIGUSR1, handle_signal); // 注册信号处理程序 while(1) {} // 循环等待信号 return 0; } ``` 上面的代码中,signal函数用于注册信号处理程序,当接收到SIGUSR1信号时会执行handle_signal函数。循环部分是为了等待信号的到来。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值