原来进程是这样子的啊

进程与程序:

​ 程序就是存储在磁盘上包含可执行指令、数据的静态实体(可执行文件)。

​ 进程就是被操作系统读取加载到内存中的正在执行的程序。

进程的分类:

守护进程:

​ 由系统在开机时通过启动脚本激活的,总处于活动状态,一般运行在后台维护系统的正常运行,进程号为1

批处理进程:

​ 系统会每隔一段时间集中处理该类进程的相关指令,会有一定的延时,但避免的状态切换的耗时因此执行效率高

交互进程:

​ 在执行需要用户输入一些数据否则无法继续执行

Linux/UNIX系统查看进程:

​ 简单形式:ps 以简略方式显示当前用户当前终端有控制权的进程

详细显示:ps auwx

	a:所有用户的当前终端有控制权的进程
	u:显示详细信息
	x:包含无控制权进程
	w:以更大列宽显示

进程的信息列表:

USER		进程属主
PID			进程IP
%CPU		CPU使用率
%MEM		内存使用率
VSZ 		使用虚拟内存的大小(kb)
RSS			使用武力内存的大小(kb)
TTY			终端设备号(表示他被哪个终端控制着),?表示无终端控制
STAT		进程的状态
	O	就绪态,所有准备工作都已经完成,等待被系统执行
	R	运行状态的进程,Linux系统中没有就绪态,就绪态也用R表示
	S	可被唤醒的睡眠,当收到系统中断、获取到资源、手动信号都可以从进程唤醒转入运行状态
	D	不可唤醒的睡眠,只能被系统调用wake_up唤醒
	T	暂停,收到信号SIGSTOP进程将转为暂停状态,收到SIGCONT信号转为进行状态
	Z	僵尸状态,进程已经结束运行,但其父进程还没有回收他的资源

	s	会话首进程
	l	多线程进程
	<	高优先级进程
	N	低优先级进程
	+	前台进程
START		进程的启动时间
TIME		进程的运行时间
COMMAND		启动进程的程序123

父进程和子进程:

​ 1.一个进程可以创建另一个进程,创建者叫父进程,被创建者叫子进程

​ 2.父进程启动子进程后,子进程会在操作系统的高度下与父进程同时执行

​ 3.子进程先于父进程结束时,会向父进程发送SIGCHLD信号,父进程收到SIGCHLD信号后就应该去回收子进程的相关资源。如果父进程没有及时回收,子进程将变成僵尸进程

​ 4.父进程先于子进程结束,子进程就会变成孤儿进程,同时会被inie进程收养,即成为init的子进程,而init进程也叫孤儿院

进程标识符:

​ 1.每个进程都会有一个以非负数表示的唯一的标识,也就是进程ID,相当于进程的身份证号

​ 2.进程在任何时候都是唯一的,但可以重用,当一个进程结束时,它的进程ID就可以被其他进程使用(延时重用)

pid_t getpid(void);
功能:获取当前进程的进程ID

pid_t getppid(void);
功能:获取当前进程的父进程ID

fork创建进程:

pid_t fork(void);
功能:创建一个子进程
返回值:
	成功返回两次,子进程返回0,父进程返回子进程的ID
	失败返回一次-1

​ 1.通过fork创建的子进程会拷贝父进程的代码段、全局数据段、静态数据段、堆、栈、IO缓冲区、文件表。

​ 2.进程创建完成后,父子进程各自独立运行,先后顺序不确定。

​ 3.当进程的总数超出系统限制,fork将创建失败

​ 4.通过fork创建的子进程会继承父进程的信号处理方式

vfork创建进程:

pid_t vfork(void)
功能:创建子进程
返回值:
	失败返回一次-1
	成功返回两次,子进程返回0,父进程返回子进程的ID

​ 区别:

​ vfork创建的子进程不会复制父进程的代码段资源,而是通过exec系列函数直接加载一个可执行文件启动子进程

​ 注意:子进程创建成功前,子进程暂时借用父进程的相关资源来加载子进程,而此时的父进程是阻塞状态,只有子进程创建成功后,父进程才继续执行。

​ 通过vfork创建的子进程不会继承父进程的信号处理方式

int execl(const char *path, const char *arg, ...);
path:可执行文件的路径
arg:命令行参数,至少一个,且以NULL结尾
注意:必须以NULL结尾

int execlp(const char *file, const char *arg, ...);
file:可执行文件名,该文件必须存储在PATH环境变量的路径下
arg:命令行参数,至少一个,且以NULL结尾

int execv(const char *path, char *const argv[]);
int execvp(const char *file, char *const argv[]);
argv:存储命令行参数的字符串数组,最后一个必须是NULL

system创建进程:

int system(const char *command);
功能:加载一个可执行程序创建子进程
返回值:成功返回0,失败返回-1
区别:子进程执行时,父进程阻塞,子进程之行结束后父进程才继续

进程的正常退出:

​ 1.从main函数return

​ 2.调用标准C函数exit

​ 无论在任何时候的任何位置调用此函数的进程会立即结束

void exit(int status);
功能:结束当前进程,该函数一旦执行就不会返回
status:进程的结束状态码,与main函数中的返回值具有同样的意义,反映了进程是如何结束的,父进程调用相关函数可以获取到status的第八位,常用的参数:EXIT_SUCCESS,EXIT_FAILURE

注意:进程在结束之前会先执行atexit/on_exit注册的函数,然后再调用_exit/_Exit函数
	int atexit(void (*function)(void));
	int on_exit(void (*function)(int , void *), void *arg);
	功能:向内存注册一个函数,进程结束时自动执行被注册的函数

	void (*function)(int , void *)
	int:exit函数的参数或者return的返回值
	void*:是on_exit注册时的第二个参数

​ 3.调用_exit/ _Exit函数

void _exit(int status);
功能:Linux系统提供的进程结束函数

void _Exit(int status);
功能:标准库提供的等价于_exit的进程结束函数,目的是为了提高代码的兼容性

1.status可以是exit函数的参数,也可以是用户提供的,父进程调用相关函数可以获取status的第八位

2.冲刷所有文件的缓冲区,关闭所有文件

3.把子进程托付给init进程收养

4.取消所有的虚拟内存映射

5.向父进程发送SIGCHLD信号

​ 4.进程的最后一个线程执行了返回语句

​ 5.进程的最后一个线程调用了pthread_exit函数

进程的异常中止:

​ 1.进程接受到某些信号(他杀)

​ 2.调用abort函数(自杀)

​ 3.最后一个线程对“取消”请求作出响应(让你死你还真去死了)

回收子进程

pid_t wait(int *status);
功能:等待所有子进程结束,如果所有子进程都在运行,则父进程阻塞
返回值:
	1.如果没有子进程,则返回错误ECHILD
	2.只要由一个子进程结束,则返回子进程的进程ID和结束状态码

pid_t waitpid(pid_t pid, int *status, int options);
功能:等待指定的子进程结束,回收子进程
pid:
	1.< -1	等待进程组号为pid的绝对值的进程结束
	2.= -1	等待任意子进程结束
	3.=  0	等待组进程ID为当前ID的进程结束
	4.>  0	等待进程ID为pid的进程结束
options:
	WNOHANG		如果没有子进程则立即返回
	WUNTRACED	子进程停止立即返回
	WCONTINUED	子进程由暂停状态转为继续状态页返回
返回值:
	1.如果没有子进程,则返回错误ECHILD
	2.只要由一个子进程结束,则返回子进程的进程ID和结束状态码
	
解析status的宏:
	WIFEXITED(status)	检查进程是否正常退出
	WEXITSTATUS(status)	获取status的第八位,但只有WIFEXITED(status)为真时才有意义
	WIFSIGNALED(status)	检查进程是否被信号中止
	WTERMSIG(status)	获取导致进程中的信号WIFSIGNALED(status)结果为真时才有意义
	WCOREDUMP(status)	检查进程是否是否由于核心转储结束(段错误)
	WIFSTOPPED(status)	结果为真时才有意义
	WSTOPSIG(status)	获取导入进程暂停的信号,WIFSTOPPED(status)结果为真才有意义
	WIFCONTINUED(status)当进程由暂停转换为继续运行进程返回真

​ 当父进程收到子进程的SIGCHLD信号时,就应该调用wait/waitpid函数回收子进程

​ 如果子进程已经结束,在调用wait/waitpid函数之前子进程处于僵尸状态,调用后子进程会立即消失

​ 如果不关心子进程的结束状态,status的参数可以为NULL

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值