首页 > 代码库 > 进程使用的总结
进程使用的总结
当一个知识点,长时间不用的话,那么就会很容易的遗忘,这是一个很正常的规律。所以学而时习之,对我们非常有必要。
那么,这边文章就是对以前学习的进程进行复习和回顾的作用。
我们很容易的知道进程就是程序的一次执行过程,每个进程创建的时候有独立的4GB的空间,有自己的代码段,数据段,堆栈等资源。
linux系统下主要包括下面几种进程: 交互式进程,批处理进程,守护进程
一 、运行进程需要那些资源 ?
CPU资源 ,内存资源,时间片资源
二 、进程与程序
程序:一个存放在磁盘上的可执行文件
进程:是程序的一次执行过程,伴随着资源的分配和释放。相对于OS而言。
三 、进程的组成
栈 ,堆,ro data,data段,bss段,代码段,一组寄存器值[pc]
四 、Linux 对进程描述
PID :标识一个进程
PPID :标识父进程
进程内存空间
进程状态 :
(1)运行状态:(TASK_RUNNING)进程正在运行,或者正在运行队列中等待调度。
(2)可中断的阻塞状态(TASK_INTERRUPTIBLE):可以被信号中断,接收到信号则被唤醒变为运行的状态,
(3)不可中断的阻塞状态(TASK_UNINTERRUPTIBLE):不会处理信号,所以信号不能改变它的运行状态,只有在它所等待的事件发生的时候,进程才被显示的唤醒。
(4)暂停状态(TASK_STOPPEND):进程的执行被暂停,当进程收到SIGSTOP,SIGTSTP,SIGTTIN,SIGTTOUT等信号,就进入暂停状态。
(5)僵死状态(EXIT_ZOMBIE):子进程结束而没有被父进程回收的状态 。
linux首先把终止的进程设置为僵死状态,这个时候进程已经无法运行,它的存在只为父进程提供信息,父进程在某个时间调用wait函数族,回收子进程的退出状态,随后子进程占用的所有资源被释放。
(6)消亡状态(EXIT_DEAD):这是最终状态,当父进程调用wait函数族后,子进程彻底的由系统删除。
Linux 用task_struct 结构体描述一个进程
五、 进程相关命令
Linux内核通过唯一的进程标示符PID来标示每一个进程。
(1)查看PID和PPID
Linux系统中获得当前进程的进程号(PID)
父进程号(PPID)的系统调用函数非别为getpid(),和getppid()
ps -ef | grep 进程名或进程号
(2)查看进程的状态
ps aux | grep 进程名或进程号
D : 不可中断等待态
S : 可中断的等待态
T : 停止态
Z : 僵尸态
R : 运行态
(3)给进程发信号
kill -信号的序号 PID
查看信号的序号:
kill -l
或
killall -信号的序号 进程名
(4)运行程序的时候,指定进程的优先级
nice -值 可执行文件
nice值 [-20-19]
例如:
nice -10 ./while
nice --10 ./while
(5)更改已经运的进程nice值
renice nice值 PID
例如:
renice 10 1235
renice -10 1235
六 、创建子进程
pid_t fork(void);
功能:
创建一个子进程 ,fork(0函数通过复制当前的进程创建一个子进程,子进程和父进程的区别仅仅在于不同的PID,PPID,和某些资源以及统计量。
返回值:
成功给父进程返回子进程的PID,给子进程返回0,失败返回-1
创建子进程过程:复制父进程来创建子进程 [复制内容:代码段共享,其他都复制]
思考: 创建完子进程后,父进程从fork的下一条语句执行,子进程为什么也是从fork的下一条语句执行?
创建子进程的时候拷贝父进程的PC寄存器值 ,而PC寄存器的作用就是确定程序的下一条执行语句。
pid_t vfork(void);
功能:
创建一个子进程
返回值:
成功给父进程返回子进程的PID,给子进程返回0,失败返回-1
vfork 与 fork区别:
(1)fork创建的子进程后,父子进程执行的顺序不确定并且父子进程的地址空间是独立的
(2)vfork创建完子进程后,保证子进程先执行,父进程在子进程结束或子进程调用了exec函数族后,才开始运行。
并且父子进程共享同一个地址空间[如果子进程调用了exec函数族,则子进程会独立出来]
七 、exec函数族
功能 : 在一个进程中执行另外一个程序
Linux下使用exec函数族主要有两种情况:
(1)当进程认为自己不能再为系统和用户做出任何贡献时,就可以调用exec函数族中的任意一个函数让自己重生。
(2)如果一个进程想执行另外一个程序,那么它就可以调用fork()函数新建一个进程,然后调用exec函数族中的任意一个函数,这样看起来就像通过执行应用程序而产生了一个新的进程(这种情况非常普遍)
思考 : exec函数族如何执行另外一个程序 ?
用新程序的代码段,数据段,堆栈替换原程序,只保留原进程的PID,其他全部替换
实际上, 在Linux中并没有exec()函数,而是有6个以exec开头的函数:下面将慢慢的解释常用的几种
l :参数以列表的形式传递
int execl(const char *path, const char *arg, ...);
参数:
@path 可执行程序的路径
@arg 可执行程序的名字
@arg1 给可执行程序传递的第一个参数
@arg2 给可执行程序传递的第二个参数
...
@最后一个参数写成NULL
返回值:
成功返回0,失败返回-1
例如:执行/bin/ls ,传递的参数-l
execl("/bin/ls","ls","-l",NULL);
v:参数以指针数组的形式传递
int execv(const char *path, char *const argv[]);
char *p_arry[] = {"ls","-l",NULL};
execv("/bin/ls",p_arry);
p:执行的可执行程序从PATH环境变量中搜索
int execlp(const char *file, const char *arg, ...);
execlp("ls","ls","-l",NULL);
------------------------------------------------------------
int execvp(const char *file, char *const argv[]);
char *p_arry[] = {"ls","-l",NULL};
execvp("ls",p_arry);
exec函数族
e:执行程序的时候,可以给程序传递环境变量
int execle(const char *path, const char *arg,..., char * const envp[]);
char *envp[] = {"PATH=/home/linux","TEST=HELLO WORD",NULL} ;
进程使用的总结
声明:以上内容来自用户投稿及互联网公开渠道收集整理发布,本网站不拥有所有权,未作人工编辑处理,也不承担相关法律责任,若内容有误或涉及侵权可进行投诉: 投诉/举报 工作人员会在5个工作日内联系你,一经查实,本站将立刻删除涉嫌侵权内容。