进程基础
a.从程序到进程
1.内核将程序读入内存,为程序镜像分配内存空间。
2.内核为该进程分配进程标识符PID。
3.内核为该进程保存PID及相关的进程状态信息。
b.程序格式ELF
Executable and Linkable Format文件格式,一种用于二进制文件、可执行文件、目标代码、共享库和核心转储格式文件。
查看程序(ELF):readelf -S 文件名
查看进程空间大小:size 文件名
c.虚拟存储器/虚拟地址空间
进程的概念:
进程与程序的区别
1.进程是动态的,而程序是静态的
2.进程有生命周期,二程序是指令集合
3.一个进程只能对应一个程序,而一个程序可以改对应多个进程
进程的状态可以分为三类:
1.就绪(Ready)
2.运行(Running)
3.阻塞(Blocked)
进程脚本:
###如何查看进程
Windows:
tasklist:tasklist/FI *PID eq进程PID*
Linux:
1.ps:USER(用户)PID(进程ID)%CPU(进程占用的CPU百分比)%MEM(占用内存的百分比)VSZ(进程虚拟大小)RSS(常驻内存[内存中的页的数量])TTY(终端ID)STAT(启动进程的时间)TIME(进程消耗CPU的时间)COMMAND(命令的名称和参数)
查看某些进程
ps -p 进程PID
ps -C 命令行
查看进程
ps -aux BSD风格 a:终端上所有用户的进程;u:以用户为中心显示详情信息;x:无终端进程
ps -ef System风格 e:所有进程;f:树状显示
ps进程状态显示:D(不可中断Uninterruptible[usually IO]) R(正在运行,或在队列中的进程) S(处于休眠状态) T(停止或被追踪) Z(僵尸进程) X(死掉的进程) <(高优先级) n(低优先级) s(包含子进程) +(位于后台的进程组)
2.pstree:以树状图的方式展现进程之间的派生关系(安装:yum install psmisc)
3.top:实时显示系统中各个进程的资源占用(类似Windows的任务管理器)
###如何创建进程
Windows:
程序名
Linux:
程序名
###如何杀死进程
Windows:
taskkill /F /PID 进程标识
taskkill /F /IM 程序名
Linux:
kill 进程标识PID
进程文件
/proc/
进程操作
###进程标识pid
类比:身份证号(计算机是数学学霸,经常使用数字起名,例如:IP地址)
获取PID
pid_t getpid() 获取当前进程ID
pid_t getppid() 获取当前进程父进程ID
###如何创建进程
区别:
fork()复制父进程
system()阻塞父进程
exec()替换原进程
pid_t fork()
返回值
-1:失败
0:子进程逻辑控制流
其他(子进程PID):父进程逻辑控制流
特点
调用一次,返回两次
相同但是独立的地址空间
并发执行
并发concurrency
两个或多个进程在同时存在
单核
进程指令同时或交错执行
并行parallellism
共享文件
本质:复制+分叉
exec函数
分类:v[第二个参数是数组] l[第二个参数之后是变参] p[第一个参数是文件名] e[最后一个参数是环境变量]
字符串数组参数
execv()
execvp()
execve()
可变参数[printf()是典型的可变参]
execle()
execlp()
execl()
返回值
-1:失败
不返回:成功
特点
一次调用,失败返回
改朝换代,取而代之
PID不变
地址空间内容变化
本质
覆盖程序
int system(Shell字符串)
返回值
-1:失败
127:无法启动shell来运行
其他:命令退出码
特点
一次调用,一次返回
本质
shell执行命令/程序
###如何结束进程
进程的结束与生命结束相似。
return和exit()属于寿终正寝,并且了结后事。
_exit()也属于自杀,但是没有料理后事。
abort()属于意外死亡(车祸、病死),也没有料理后事。
信号终止就是他杀。
main()函数return 0与exit(0)区别:
main()函数return 0 是语言级别的退出,退出后自动调用exit(0)
exit(0)是函数级别的退出。
exit(0)与abort()区别
exit(0)释放所有的静态的全局的对象,缓存,关掉所有的I/O通道,然后终止程序。
abort()直接终止程序,不释放资源。
exit(0)与_exit()区别
exit()函数在调用_exit()系统调用之前要检查文件的打开情况,把文件缓冲区中的内容写回文件,清理I/O缓冲。
exit(0)是标准C函数。
_exit()不做清理I/O缓冲处理。_exit()是Linux系统调用。
main函数退出
return返回
只能在main函数内
调用exit()函数
一般用在main函数以外的函数
调用_exit()函数
一般用来结束子进程
调用abort()函数
一般用来异常退出
信号终止
终止其他进程
###如何停止进程
休眠 int sleep(unsigned int secs)
secs:指定休眠的秒数[-1:永久休眠]
返回值:未休眠的秒数
特性:如果没有信号中断,休眠指定秒数返回0,否则马上返回休眠的秒数
暂停 int pause()
返回值:总是-1
特性
等待信号
Ctrl+C SIGINT 中断
Ctrl+Z SIGTSTP 终端的停止信号
如果程序没有处理信号,直接中断,执行默认信号处理,程序后续代码不再执行。
如果程序存在信号处理,执行信号处理后,执行后续代码。
等待
pid_t wait(int* status) 等价pid_t waitpid(-1,status,0)
pid_t waitpid(pid_t pid,int* status,int options)
pid 等待的进程
<-1:等待进程组为pid的所有进程
-1:等待任何子进程
0:等待同组的进程
>0:进程为pid的子进程
status 子进程结束状态
正常结束
WIFEXITED(status)
非0:正常结束子进程
0:非正常结束子进程
WEXITSTATUS(status)
取得子进程exit()返回的结束代码
一般会先用WIFEXITED来判断是否正常结束才能使用此宏
异常结束
WIFSIGNALED(status)
非0:异常结束子进程
0:非异常结束子进程
WTERMSIG(status)
取得子进程因信号而中止的信号代码
一般会先用WIFSIGNALED来判断后才使用此宏
暂停
WIFSTOPPED(status)
非0:暂停结束子进程
0:非暂停结束子进程
WSTOPSIG(status)
取得引发子进程暂停的信号代码
一般会先用WIFSTOPPED来判断后才使用此宏
option 选项
WNOHANG:若子进程没有结束,返回0,不予以等待,若子进程结束,返回该子进程的ID
WUNTRACED:若子进程进入暂停状态,则马上返回,但子进程的结束状态不予理会。
返回值
其他:等待PID
-1:失败
其他
孤儿进程
父进程先于子进程退出
init进程作为新的父进程
无害
僵尸进程
子进程退出,父进程没有获得子进程的状态信息[调用wait或waitpid]
避免出现僵尸进程
进程实例:简易shell