【推荐】进程的创建,等待, 终止的实现

进程创建

  从已存在的进程中,创建一个具有独立地址空间的新的进程,且新创建的进程为子进程。

函数:pid_t fork(void);

   1. 子进程中返回0
   2. 父进程返回子进程id
   3. 出错返回-1

   fork之前,父进程独立执行,fork之后,父子两执行流分别执行。
   fork之后,谁先执行完全由调度器决定。

vfork:

   1. 创建子进程,而子进程与父进程共享地址空间。
   2. 保证子进程先运行,在调用exec或exit之后父进程才可能被调度运行。

代码实现

  1 #include<stdio.h>
  2 #include<unistd.h>
  3 #include<stdlib.h>
  7 int main()
  8 {
  9    int g_val=0;
 10     pid_t id=fork();          //创建进程
 11     if(fork<0)                //创建 失败
 12     {
 13         perror("fork");
 14         return 0;
 15     }
 16     else if(fork==0)            //子进程
 17     {
 18         //child 
 19         g_val=100;
 20         printf("child[%d] :  %d  : %p\n", getpid(), g_val ,                    &g_val);
 21 
 22     }
 23     else                         //父进程
 24     {
 25         //parent
 26         sleep(3);  //睡着三秒再打印,此时子进程已经退出,父进程执行。
 27         printf("parent[%d] :  %d  : %p\n",getpid(), g_val, &g_val);
 28     }
 29     sleep(1);
 30   return 031 }

进程终止

_exit函数(强制退出)

原型:void _exit(int status);

 参数:status定义了进程的中止状态,父进程通过wait来获取该值。

exit函数(清空缓冲区)

       原型:void exit(int status);

exit最后也会调用_exit,但在调用之前,还做了其他工作:

  1.执行用户通过atexit或on_exit定义的清理函数

  2.关闭所有打开的流,所有的缓存数据均被写入

  3.调用_exit

进程退出场景:

1.代码运行完毕,结果正确;
2.代码运行完毕,结果不正确;
3.代码异常终止。

进程常见退出方法:

  • 正常终止(可通过echo $? 查看进程退出码)

     1.从main返回
    
     2.调用exit
    
     3._exit
    
  • 异常退出:Ctrl + c,信号终止

  1 #include<stdio.h>
  2 #include<unistd.h>
  3 #include<stdlib.h>                                                          
  4 int main(void)
  5 {
  6 
  7     printf("himark\n");
  8     exit(0);
  9 }

这里写图片描述

进程等待

- 进程等待的原因

    1.子进程退出,父进程若不管不顾,就可能造成“僵尸进程”的问题,进而造成内存泄漏。

    2.进程一旦变成僵尸状态,kill -9也无能为力。

    3.父进程需要通过进程等待来接收子进程的退出信息,回收子进程的资源。

函数pid_t wait(int* status)

返回值

   成功返回被等待进程pid,失败返回-1。

参数

   输出型参数,获取子进程退出信息,不关心则可以设置成NULL。

函数pid_t waitpid(pid_t pid,int* status,int options);

返回值:

    1. 当正常返回的时候waitpid返回收集到的子进程的进程ID; 

    2. 如果设置了选项WNOHANG,⽽而调⽤用中waitpid发现没有已退出的子进程可收集,则返回0; 

    3. 如果调用中出错,则返回-1,这时errno会被设置成相应的值以指示错误所在。

参数设置

pid

  pid=-1,等待任一个子进程,与wait等效。

  pid>0,等待进程ID与pid相等的子进程。

status:

     WIFEXITED:若为正常终止子进程返回的状态,则为真。

     WEXITSTATUS:若WIFEXITED非零,提取子进程退出码。

options:

     WNOHANG:若pid指定的子进程没有结束,则waitpid()函数返回0,不予以等待。若正常结束,则返回该子进程的ID。
  1 #include<stdio.h>
  2 #include<sys/wait.h>                                                                                                                                                                       
  3 #include<unistd.h>
  4 #include<stdlib.h>
  5 
  6 int main()
  7 {
  8     pid_t pid;
  9     pid=fork();
 10     if(pid<0)
 11     {
 12         printf("%s fork error\n",__FUNCTION__);
 13             return 1;
 14     }
 15     else if(pid==0)
 16     {
 17         printf("child is run , pid is %d\n", getpid());
 18         sleep(5);
 19         exit(257);
 20     }
 21     else
 22     {
 23         int status=0;
 24         pid_t ret=waitpid(-1,&status, 0);
 25         printf("this is test for wait\n");
 26         if(WIFEXITED(status)&&ret==pid)
 27         {
 28             printf("wait child 5s success, child return code is:%d\n",WEXITSTATUS(status));
 29         }
 30         else
 31         {
 32             printf("wait child failed,return \n");
 33             return 1;                                                                                                                                                                      
 34             
 35         }
 36     }
 37     return 0;
 38 }
 39 

这里写图片描述

猜你喜欢

转载自blog.csdn.net/yu876876/article/details/79858248