什么是进程?

一、基本概念

1、进程与程序

程序就是存储在磁盘上的,包含可执行机器指令的有限集合。
进程就是处在活动状态的程序,一个程序可以有多个正在运行的进程。

2、进程的分类

交互进程:普通的应用型的进程,有数据输入、输出。
批处理进程:由脚本语言开启的进程,如:bat,shell
守护进程:由操作系统开机时通过开机脚本自动启动的进程,它负责操作操作的维护和支持工作,运行在后台。

3、查看进程
a、简单形式查看:

ps.以简略形式显示当前用户有控制权限的终端进程信息。

b、以列表形式查看:
	ps aux
	a 所以用户有控制终端的进程
	x 包括无终端控制的进程
	u 以详细方式显示
c、进程信息列表
		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、从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);
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值