关于进程

一、基本概念
1、进程与程序
程序就是存储在磁盘上的,包含可执行机器指令的有限集合。
进程就是处在活动状态的程序,一个程序可以有多个正在运行的进程。
2、进程的分类
交互进程:普通的应用型的进程,有数据输入、输出。
批处理进程:由脚本语言开启的进程,如:bat,shell
守护进程:由操作系统开机时通过开机脚本自动启动的进程,它负责操作操作的维护和支持工作,运行在后台。
3、查看进程
1、简单形式查看:
ps 以简略形式显示当前用户有控制权限的终端进程信息。
2、以列表形式查看:
ps aux
a 所以用户有控制终端的进程
x 包括无终端控制的进程
u 以详细方式显示
3、进程信息列表
USER:进程的属主
PID:进程号
CPU:cpu使用率
MEM:内存使用率
VSZ:占用虚拟内存的大小
RSS:占用物理内存的大小
TTY:是否由终端控制,"?"表示无终端控制
STAT:进程状态
O:就绪态,等待被调度。
S:可被唤醒的睡眠态,如系统中断、获取到资源、收到信号都可被唤醒。
R:运行态,正在被执行。
D:不可被唤醒状态,只能被wake_up系统调用唤醒。
T:暂停,收到SIGSTOP会进程这种状态,只有收到SIGCONT时才转入运行态。
W:等待内存分页,2.6内核后废除了。
Z:僵尸态
L:被锁到内存中的分页
l:多线程进程
/+:在前台的进程组中
N:低优先级进程
<:高优先级进程
s:会话进程
START:进程开始时间
TIME:进程的运行时间
COMMAND:由那个程序文件加载的
4、进程之间的关系
一个进程A可以创建另一个进程B,创建者叫做父进程,被创建者叫子进程。
当父进程创建出子进程后,父子进程一起运行。
子进程如果先结束,它会向父进程发送SIGCHLD信号,父进程就应该去回收子进程。
如果父进程先于子进程结束,子进程就变成了孤儿进程,会被孤儿院(init 1)收养,就变成了孤儿院的子进程。
如果子进程先于父进程结束,但父进程并没有及时回收子进程的相关资源,子进程就会变成僵尸进程。
5、进程标识符
每一个进程都会有一个唯一的标识符,以非负整数形式存在,进程ID。
进程ID在任何时刻都是唯一的,可以重用,当一个进程结束后,它的进程ID就可以被新的进程使用(延时重用)。
pid_t getpid(void);
功能:获取当前进程的ID

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

二、fork
pid_t fork(void);
功能:创建一个子进程,失败返回-1(进程的数量达到系统的限制)。
返回值:一次调用,两次返回。
父进程返回子进程的ID,这是父进程唯一一次获取子进程ID的机会。
子进程返回0,根据不同返回值,进入不同的分支。
1、子进程是父进程的副本
子进程会获得父进程的数据段、堆、栈(IO流缓冲区)的拷贝,并与父进程共享代码段。
2、fork函数调用后,父子进程各自继续运行,先后顺序不确定。
3、父进程会共享打开的文件,二者共享一个文件描述符(内核级)。

问题1:子进程会不会继承父进程的信号处理方式?
	会的
问题2:子进程会不会继承父进程的信号屏蔽掩码?
	会的
问题3:父进程如何知道子进程什么时候结束了?
	子进程结束时会向父进程发送信号(SIGCHLD)。

三、进程的正常退出
1、从main函数中return。

2、调用标准C语言的exit函数。
	1、父进程可以获取到exit的退出码(低八,按无符号格式解析)。
	2、在退出前会调用通过atexit/on_exit注册的函数。
		int atexit(void (*function)(void));
		功能:注册一个函数,在进程退出时执行。
		funcation:函数名或函数指针,不需要再数,不需要返回值。
		
		int on_exit(void (*function)(int , void *), void *arg);
		功能:注册一个函数,在进程退出前执行
		function:函数指针或函数名,格式要求:无返回人址
		arg:退出时传给funcation的第二个参数
		
		注意:先执行on_exit注册的再执行atexit注册的。
		
	3、exit函数不会有返回值。
	4、exit底层调用的是_exit/_Exit函数。
3、_exit/_Exit函数
	1、会把退出状态码返回给父进程。
	2、刷新所有的文件缓冲区,关闭所有打开的文件描述符。
	3、把所有的子进程托付给init,然后再给父进程发送SIGCHLD信号。
	4、没有返回值。

四、进程的异常终止
1、调用abort函数,产生SIGABRT信号。
2、进程收到一些信号。
3、最后一个线程响应的取消操作。

五、wait/waitpid
pid_t wait(int *status);
功能:等待子进程终端,并获取终止状态。
status:子进程的结构状态码。
需要使用一些宏来解析,不能直接使用。
WIFEXITED(status):判断是否是由exit/_exit/_Exit函数退出的。
WEXITSTATUS(status):获取exit的退出码。
WIFSIGNALED(status):获取杀死子进程的信号
返回值:子进程的进程号。
注意:如果所有子进程都在运行,wait会阻塞,只要有一个子进程结束它就会返回,如果没有子进程则立即返回失败,如果一旦有僵尸进程会立即返回。

pid_t  waitpid(pid_t   pid,   int   *status,   int
   options);
功能:等待指定的子进程结束
pid:要等待的子jinchengid
	< -1 等待进程号是pid的绝对值的进程结束。
	= -1 等待任意子进程结束,与wait功能一致。
	= 0 等待和当前进程同组的进程结束。
	> 0 等待进程号是pid的进程结束。
options:
	WNOHANG:非阻塞模式,如果没有要等待的进程,则立即结束。
	WUNTRACED:如果要等待的进程处于stop状态,则立即结束。
	WCONTINUED:如果要等待的进程从stop状态转为continue状态,则立即结束。

六、进程组
pid_t getpgrp(void);
功能:获取当前进程组的id

int setpgid(pid_t pid, pid_t pgid);
功能:指定pid进程的进程号为pgid
注意:只能为子进程设置进程组id

七、vfork+exec创建进程
pid_t vfork(void);
功能:创建一个进程,先运行子进程,此时子进程使用的是父进制的代码空间、堆、栈等资源,接下来应该替换子进程的代码段、数据段、堆、栈等资源,让子进程独立运行,等子进程开始独立运行之后,父进程才会继续运行。
返回值:子进程返回0,父进程返回子进程的id。

int execl(const char *path, const char *arg, ...);
功能:根据可执行文件的路径加载可以执行文件
path:可执行文件的路径
arg:给可执行文件的main附加的参数,arg0可以执行文件的文件名,以NULL结束。
示例:execl("hello","hello",NULL);

int execlp(const  char  *file,  const  char  *arg,...);
功能:在PATH环境变量配置的路径下根据可执行文件名加载可执行文件

int execle(const char *path, const char *arg,..., char * const envp[]);
功能:在execl的基础上把父进程的环境变量表传给子进程

int execv(const char *path, char *const argv[]);
int execvp(const char *file, char *const argv[]);
int execvpe(const char *file, char *const argv[],char *const envp[]);
功能:与上述三个函数一至,但参数以指针数组的方式提供
char* argv[] = {"hello","hehe",NULL};
execv("/home/zhizhen/UNIX_Linux环境高级编程day06/hello",argv);
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值