进程 创建 等待 与 终止

进程创建等待与终止

进程的创建:

Linux通过fork函数进行进程的创建
他从已存在的进程中创建一个新进程。新进程为子进程,而原进程为父进程。

#include <unistd.h>
pid_t fork(void);
子进程返回0,父进程返回子进程pid,出错返回-1

进程调用fork后,内核分配新的内存块和内存数据结构给子进程,将父进程部分数据结构内容拷贝至子进程,添加子进程到系统进程列表中,fork返回,开始调度器调度

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

父子代码共享,父子不再写入时,数据也是共享的。当有一方试图写入时,便以写时拷贝的方式各自私有一份。

fork的常规用法:
一个父进程希望复制自己,使父子进程同时执行不同的代码段。
一个进程要执行一个不同的程序。

fork调用失败的原因:
  • 系统中有太多的进程(资源不够用,有上限,pcb太大)
  • 实际用户的进程数超过了限制。

vfork用于创建一个子进程,而子进程和父进程共享地址空间,fork的子进程具有独立的地址空间。
vfork保证子进程先运行,在他调用exec或exit之后父进程才可能被调度运行。

 1 #include <stdio.h>
    2 #include <unistd.h>                                                              
    3 #include <sys/types.h>                                                           
    4                                                                                  
    5 int a=100;                                                                       
    6 int main()                                                                       
    7 {                                                                                
    8   pid_t id=vfork();                                                              
    9   if(id==-1)                                                                     
   10   {                                                                              
   11     perror("fork");                                                              
   12     exit(1);                                                                     
   13   }                                                                              
   14   if(id==0)                                                                      
   15   {                                                                              
   16     //child                                                                      
   17     a=200;                                                                       
   18     printf("%d\n",a);                                                            
   19     exit(1);                                                                     
   20   }else{                                                                         
   21     //parent                                                                     
   22     printf("%d\n",a);                                                            
   23   }
   24   return 0;                                                                      
   25 }                    

进程终止

进程终止的三种情况:

  • 代码运行完毕,结果正确
  • 代码运行完毕,结果不正确
  • 代码异常终止
进程常见的退出方法

正常终止(可以通过echo $? 查看进程退出码)
$? 用来保存最近一条进程的退出码

1.从main返回 (main的返回值,正确为0不正确不为0)

2.调用exit

3.调用_exit
exit与_exit的区别:

扫描二维码关注公众号,回复: 3687343 查看本文章

_exit:不刷新内存的缓存区

exit: 会刷新内存的缓存区

异常退出:
ctrl+c 信号终止

#include <unistd.h>

void _exit(int status);
void exit(int ststus);
//status 定义了进程的退出状态,父进程通过wait获取该值,但是仅有低八位可以被父进程使用

exit在最后还是会第调用_exit,但此之前要

  • 执行用户定义的清理函数

  • 关闭打开的流,刷新缓冲

进程等待

僵尸进程无法被杀死,只能被回收

  • 父进程回收子进程的资源,避免内存泄漏

  • 获取子进程的退出信息,以此来判断子进程的退出状态

进程等待的方法

wait

#include <sys/types.h>
#include <sys/wait.h>

pid_t wait(int* status)

成功返回子进程的pid,失败返回-1

输出型参数,获取进程退出状态,不关心可以设置位NULL

如果有多个子进程,父进程等待任意一个退出的子进程

waitpid

#include <sys/types.h>
#include <sys/wait.h>
pid_t waitpid(pid_t pid,int* status,int options)

返回值:
- 当正常返回时,外套披的返回收集到的子进程的id;

- 如果设置了选项WNOHANG,而调用中的waitpid发现没有可收集的子进程的pid则返回0;
 
- 如果调用中出错,则返会1,这时erron会被设置成相应的值以知识错误的所在


参数:
pid:
   pid=-1,等待任意一个子进程,与wait等效
   pid=0,等待id与其相等的子进程
status:
  WIFEXITED(status):若为正常终止子进程则返回为真(查看进程是否正常退出)
  WEXITSTATUS(status):若WIFEXITED非0,提取子进程的退出码(查看进程的退出码)
 options:
 WNOHANG:若pid指定的子进程没有结束,waitpit()返回0,不予等待。如果正常退出,返回u该进程的id.

如果子进程已经退出,调用wait/waitpid时,wait/waitoid会立即返回,回收资源,获取子进程退出信息。

如果在任意时刻调用wait/waitpid,子进程存在且正常运行,则进程可能阻塞。

如果不存在该进程则立即出错返回

程序等待调用结果时的状态

阻塞式

就是指在执行设备操作时若不能获得资源则挂起操作,直到满足可操作的条件后再进行操作,被挂起的进程进入休眠状态,被从调度器的运行队列移走,直到等待的条件满足。

非阻塞式:进程在不能进行设备操作时并不挂起,它或者放弃,或者不停的查询,直到可以进行位置。

周期性的去检测某项事物是否发生是基于非阻塞轮寻式

获取子进程status

wait 和waitpid都有一个status参数,该参数是一个输出性参数,由操作填充

如果传递NULL表示不关心子进程的退出信息

status不能简单的当作整形来看,可以当作位图来看,只研究status的低16比特位

正常终止时高8位为退出状态
被信号所杀时 低七位为终止信号 第八位为core dump标志(异常退出信号)

kill -l 查看所有退出信号

1~64 无31 32

猜你喜欢

转载自blog.csdn.net/M_jianjianjiao/article/details/83301842
今日推荐