Linux操作系统 进程概念

进程

一、基本概念

1.进程与程序

程序:就是存储在磁盘上的文件,里面包含了一些可以执行的二进制指令和数据。
进程:就是运行着的程序(处于活动状态)

程序进程
程序是静态的进程是动态的
1个程序可以对应多个进程1个进程只能对应1个程序
程序是一组有序的指令集合进程由程序、数据和进程控制块(PCB)三部分组成
程序是对于用户而言,也可以叫做软件进程是对于程序员而言,是操作系统的概念

注意:在系统中只有进程没有程序

2.查看进程

1.简单形式:ps	以简略形式显示当前用户控制的终端下的进程。
2.以列表形式显示进程的详细信息:ps aux
	-a	所有用户控制的终端进程
	-u	以详细形式显示
	-x 显示包括无终端控制的进程
3.进程详细信息表
	USER:进程属主
	PID:进程ID
	%CPU:CPU占用率
	%MEN:内核使用率
	VSZ:占用虚拟内存大小
	RSS:占用物理内存大小
	TTY:终端设备号,?表示无终端控制的进程
	STAT:进程的状态
			O		就绪状态,等待被调用
			R		运行状态,Linux系统没有就绪状态,就绪态就是运行态。
			S		可被唤醒的睡眠状态,当系统中断、获得资源、收到信号都可以将它唤醒然后装入运行状态
			D		只能被wake_up系统调用唤醒的睡眠状态
			T		暂停状态,收到SIGSTOP(19)信号
			X		死亡状态
			Z		僵尸,已经停止,但父进程没有回收它的相关资源
	START:进程启动时间
	TIME:进程运行了多长时间
	COMMAD:启动进程的指令(可执行文件的名字)

3.父子进程

每一个进程都有一个以非负整数表示的唯一编号,即进程PID。

进程ID在任何时候都是唯一的,当可以重用,当进程结束时它的ID可以给新的进程用,采用的规则是延迟重用。

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

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

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

一个进程可以创建另一个进程,创建者叫父进程,被创建者叫子进程。

//fork
#include <stdio.h>

pid_t fork(void);
功能:创建一个子进程
返回值:失败返回-1,成功返回2次
	父进程:返回子进程的pid
	子进程:返回0
	根据返回值的不同可以分别为父子进程实现不同的处理分支。

fork调用后父子进程各自运行,先后顺序不确定,但某些操作系统可以保证子进程先运行。注意:父子进程谁先返回不确定。

子进程被创建时会拷贝父进程的data、bss、heap、stack、缓冲区等,唯独代码段不拷贝,父子进程共享一个代码段

fork调用结束后,父进程的文件描述符会复制到子进程中,此时子进程中也是可以继续使用的,因为所有进程共享一个文件表(内核级)。

子进程会继承父进程的信号处理方式,子进程结束后内核会向父进程发送SIGCHLD信号,父进程默认的处理该信号的方式是忽略,也可以捕获后回收子进程的资源。

注意:系统中的总进程数是有限的,当进程过多超过限制时,fork就会失败(不要轻易尝试,当fork前系统就会卡的不行)。

// vfork
pid_t vfork(void);
功能:创建子进程

/*以下一系列函数的功能就是配合vfork创建子进程*/
int execl(const char *path, const char *arg, ...);
path:程序的路径
arg:命令行参数
    
int execlp(const char *file, const char *arg, ...);
file:只需要程序的名字,系统会去PATH环境变量的路径中来查找这个程序。
arg:命令行参数

int execle(const char *path, const char *arg,..., char * const envp[]);
envp:环境变量表,创建子进程时传递父进程的环境变量表。

int execv(const char *path, char *const argv[]);
argv:命令参数以指针数组的形式提供
vfork与fork的区别:
	1.子进程先返回,父进程等待,子进程临时占用父进程的资源,需要子进程真正创建出来后,父进程才返回。
	2.vfork无法单独创建出一个子进程,需要与exec函数配合
	3.vfork创建出的子进程不会复制父进程的相应数据内存,而是进行替换。

4.孤儿进程与僵尸进程

孤儿进程:当一个进程的父进程先于子进程结束,子进程就变成了孤儿进程,孤儿进程会被收养到孤儿院(init).

僵尸进程:当一个进程结束时,它的父进程没有回收相关资源,此进程就变成了僵尸进程。

二、进程的正常退出

1.从main函数中return
2.调用标准库函数exit
	1.EXIT_SUCCESS/EXIT_FATLURE,约定好的进程的退出状态码,把参数的低8位返回给父进程。
	2.进程退出前会调用通过atexit/on_exit函数注册的函数.
	
	int atexit(void (*function)(void));
   	功能:注册一个函数,当进程退出时调用此函数。
   	 	
    int on_exit(void (*function)(int , void *), void *arg);
    功能:注册一个函数,当进程退出时调用此函数,同时可以附加一个指针参数(如果进程是通过return从main函数退出,则不能指向栈空间,因此此时栈空间可能已经被释放)。
    3。冲刷处于打开状态的标准IO流的缓冲区,并关闭文件。
3.进程的最后一个线程执行了返回语句
4.进程的最后一个线程调用了pthread_exit函数

三、进程的异常终止

1.进程收到某些信号,他杀。
2.进程自己调用abort函数,产生了SIGABRT信号,自杀。
3.进程的最后一个线程收到取消操作,并作出响应。

四、子进程回收

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

pid_t wait(int* status);
功能:以阻塞状态等待子进程结束,并回收它的相关资源,要有一个子进程结束它就返回,如果当前进程没有子进程就立即返回。
status:获取子进程的退出状态码,需要相关的宏进行解析才能获取到。
返回值:成功返回子进程的PID,失败返回-1.

pid_t waitpid(pid_t pid, int *status, int options);
功能:以阻塞状态等待子进程结束,与wait不同的是它可以指定等待哪个进程。
pid:要等待的子进程PID
     <-1 等待进程组中的任意子进程结束
     =-1 等待任意子进程结束,此时功能与wait等价。
     =0 等待同组的任意进程结束。
     >0 此时它代表着一个特定的子进程。
        
status:获取子进程的结束状态码, 需要相关的宏进行解析才能获取到。
options:
    0 表示忽略此参数,功能与wait一样。
    WNOHANG 如果没有子进程结束立即返回。
    WUNTRACED 如果有子进程暂停也立即返回
    WCONTINUED 如果有子进程从暂停状态切换为继续状态,立即返回。
返回值:成功返回子进程的PID,失败返回-1
  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值