进程标识
每个进程都有一个非负的整数表示一个进程的id,这个id是唯一的,来标识一个进程,但是id是可重用的,当一个进程结束后,另外一个进程便可以使用这个id。
通常情况下,id为0的进程是调度进程也被称为系统进程,id为1的是init进程,这个进程读取系统初始化文件。
除了进程id,每个进程还有其他的id。
#include<unistd.h>
pid_t getpid(void) 得到一个进程的id
pid_t getppid(void) 得到一个进程的父进程的id
pid_t getuid(void) 得到一个进程的实际用户id
pid_t geteuid(void) 得到一个进程的有效用户id
pid_
t getgid(void) 得到一个进程的实际组id
pid_t getegid(void) 得到一个进程的有效组id
函数fork
#include<unistd.h>
pid_t fork(void)
函数介绍:
这个函数用来创建一个进程,这个函数使用一次返回两次,一个表示父进程返回子进程的id,一个返回0表示子进程,子进程是父进程的副本,但是子进程和父进程共享正文段(代码段)。
父进程和子进程共享打开的文件表,因此当两者对文件进行读写操作时是相互影响的,因为两者共享文件偏移量。
除了打开的文件外父进程的其他很多属性都由子进程来继承。
- 实际用户ID,实际组ID,有效用户ID,有效组ID
- 附属组ID
- 进程组ID
- 会话ID
- 控制终端
- 设置用户ID和设置组ID标志
- 当前工作目录
- 根目录
- 文件模式创建屏蔽字
- 信号屏蔽和安排
- 环境
- 连接的共享存储段
- 存储映像
- 资源限制
父进程和子进程的区别 - fork的返回值不同
- 进程ID不同
- 这两个进程的父亲ID不同
- 子进程不继承父进程的文件锁
- 子进程的未处理的闹钟被清除
- 子进程的未处理信号集设置为空集
exit函数
有五种正常终止的推出方法
- 在main函数中调用return函数,等效于exit函数
- 调用exit函数,处理各种终止处理程序,关闭标准文件I/O
- 调用_exit和_Exit函数,为进程提供一种无需处理种植处理程序和信号处理程序的终止方法
- 进程的最后一个线程在其启动例程上调用return,其返回的状态为0
- 进程的最后一线程调用pthread_exit函数,进程的终止状态为0
三种异常终止的方式 - 调用abort
- 当进程接收到某种信号时,信号的产生可以由自身或者其他进程或者内核产生
- 最后一个线程对取消做出响应
不管进程如何终止,在终止时都会调用同一段代码,目的是关闭所有的文件描述符和释放它所使用的存储器等资源。
一个子进程的终止,其父进程需要对其善后,否则被称为僵尸进程,父进程可以调用wait或者waitpid函数来接收子进程的终止状态等信息并对其善后,当一个子进程终止时其终止的状态会被暂时保存,等待父进程获取其终止状态,还有一种情况是父进程比子进程先终止,这时子进程的便会将自己的父进程设置为init进程,其工作原理是当一个进程终止时,系统便会检查所有的进程是否是即将终止进程的子进程,如果是便将这个进程的父进程ID设置为1。当一个init的子进程终止时,init进程便会自动调用wait函数来对其善后处理,防止其成为僵尸进程。
wait和waitpid函数
#include<sys/wait.h>
pid_t wait(int *statloc)
pid_t waitpid(pid_t pid,int *statloc,int options)
这个函数的作用便是等待进程的返回,并且获取进程的终止状态,如果statloc为NULL,这不获取进程的退出状态,wait函数表示当任意子进程结束时便返回,在没有子进程结束时阻塞。waitpid表示等待指定id的子进程返回。
有四个宏可以得到子进程的终止原因
- WIFEXITED(status)为真表示正常终止
- WIFSIGNALED(status)为真表示异常终止
- WIFSTOPPED(status)为真表示暂停子进程
- WIFCONTINUED(status)为暂停作业后又继续作业返回时未真
下面介绍waitpid中的pid参数
- pid==-1表示等待任意进程和wait功能一样
- pid>0表示等待pid的子进程结束
- pid==0表示等待组id等于调用组id的任意进程
- pid<-1表示等待pid的绝对值的子进程
网友评论