欢迎访问 生活随笔!

ag凯发k8国际

当前位置: ag凯发k8国际 > 运维知识 > linux >内容正文

linux

linux c :系统调用-ag凯发k8国际

发布时间:2024/10/14 linux 25 豆豆
ag凯发k8国际 收集整理的这篇文章主要介绍了 linux c :系统调用-fork,wait,subreaper 小编觉得挺不错的,现在分享给大家,帮大家做个参考.

     fork():创建子进程,并返回进程id。

     wait(&status):等待子进程终止。如果成功则会返回僵尸子进程的pid,status的值会是子进程的exitcode。

     exit(value):进程正常退出,并返回退出值value

     prctl(pr_set_child_subreaper):设置当前进程为subreaper进程。

零、示例代码即可能的输出结果

目录

一、fork()

二、wait()

三、subreaper

四、解读上述代码和输出结果


#include #include #include #include int main(){int pid ,r,status ;printf("mark process %d as a subreaper\n",getpid());r=prctl(pr_set_child_subreaper);pid = fork();if(pid){//parent printf("subreaper %d child =%d\n",getpid(),pid);while(1){pid =wait(&status);if(pid >0){printf("subreaper %d wait a zombie=%d\n",getpid(),pid);}else{break;}}}else{//childprintf("child %d parent=%d\n",getpid(),(pid_t)getppid());pid=fork();if(pid){printf("child%d start : grandchild=%d\n",getpid(),pid);printf("child%d exit : grandchild=%d\n",getpid(),pid);}else{printf("grandchild%d start : myparent=%d\n",getpid(),getppid());printf("grandchild%d end : myparent=%d\n",getpid(),getppid());}}}

运行结果:(每次运行可能顺序不一样)

      在linux 中,每个用户在同一时间只能有一定数量的进程。用户资源限制文件通常在/etc/security/limits.conf 文件中设置。进程有两种执行状态,一种是内核态,一种是用户态。每个进程都在内核中下产生并开始执行,想调用硬件设备例如操作cpu,键盘,或者想执行系统调用都是在内核态下完成的。修改状态寄存器的值就可以从内核态转化为用户态。一旦转为用户态,那么就无法直接访问硬件相关的设备,想要重新转为内核态只有3种方式:硬件中断,异常,系统调用。 可以说,内核是操作系统之下的部分,用户是操作系统之上的部分。用户只需关心操作系统为用户提供了哪些可访问内核的接口就行。

      在内核模式中,每个进程都有完全相同的代码段,数据段和堆,但是每个进程都有只属于自己的栈。

一、fork()

     创建子进程并返回子进程的pid , int pid = fork();   如果fork失败则为-1。当创建了子进程后,子进程和父进程在用户态的映像完全相同,但是在内核态下的映像只有栈有区别,意味着子进程和父进程有相同的代码和数据。因为创建子进程时用户态的栈也是一样的,意味着栈帧情况也是一样的。创建完后子进程和父进程都从fork()后继续执行.fork()方法调用了内核中kfork()函数,它对创建出来的子进程返回是0,父进程返回值是子进程的进程号;

int pid =fork(); if(pid=-1){//父进程创建子进程失败的分支 }else if(pid ==0){//子进程执行的分支,因为子进程返回的pid是0 }else {//父进程执行的分支,pid是子进程的id }

二、wait()

       等待僵尸子进程。所谓的僵尸进程,就是程序已经结束但是资源未释放的进程。wait除了返回僵尸子进程的id,获取子进程的退出状态,还会释放僵尸子进程。wait系统调用将调用内核中的kwait函数

三、subreaper

进程可以用系统调用定义自己为subreaper进程:

prctl(pr_set_child_subreaper);

      如果子进程的父进程先死亡,那么该子进程就会成为一个孤儿进程。在linux中,标记为subreaper的祖先进程会成为该孤儿的父进程,否则将成为p1进程子进程。(p1进程是操作系统初始化的进程,除p0和p1进程,其他所有进程都是p1进程的子孙进程)。不过要注意的是,当p1清理重定父级进程时,会丢失关于子进程的所有信息。p1因为进程等级高,当p1作为孤儿进程的父进程时服务管理器不能再从服务守护进程中接收sigchld信号,也不能等待任何僵尸子进程。定义subreaper就可以很好的解决上述问题,并且可以有效地减少p1进程的工作量。

显示当前用户的subreaper 进程的pid 和信息:

     ps fxau | grep username | grep "/sbin/upstart"

四、解读上述代码和输出结果

  就运行结果而言,

1)当fork创建出来子进程后,父进程获取到cpu使用权先执行,并打印出了

      

      然后进入while循环等待子进程执行结束。

2)接下来子进程执行并打印出了,

      

     之后子进程 fork 创建出了一个子进程的子进程即孙子进程。

3)子进程先执行完毕,并打印出:

      

      此时,子进程执行完毕但是未释放进程资源,于是成为了僵尸进程。

4)此时父进程获取到cpu使用权,通过wait返回子进程的pid,继续执行打印出了  

     

     wait释放了子进程的资源,使孙子进程成为了孤儿进程,但是由于之前父进程(pid=3434)将自己设置成了pr_set_child_subreaper  , 使 孙子进程(pid=3436)的父亲不再是已经死亡的(pid=3435),而是父进程(pid=3434)。

5)所以当孙子执行完自己的代码后,打印出

     成为了僵尸进程后,被父进程 wait() 释放出来,打印出

    后结束。

与50位技术专家面对面20年技术见证,附赠技术全景图

总结

以上是ag凯发k8国际为你收集整理的linux c :系统调用-fork,wait,subreaper的全部内容,希望文章能够帮你解决所遇到的问题。

如果觉得ag凯发k8国际网站内容还不错,欢迎将ag凯发k8国际推荐给好友。

  • 上一篇:
  • 下一篇:
网站地图