Linux的进程管理(一).ppt

上传人:牧羊曲112 文档编号:5438098 上传时间:2023-07-07 格式:PPT 页数:51 大小:1.44MB
返回 下载 相关 举报
Linux的进程管理(一).ppt_第1页
第1页 / 共51页
Linux的进程管理(一).ppt_第2页
第2页 / 共51页
Linux的进程管理(一).ppt_第3页
第3页 / 共51页
Linux的进程管理(一).ppt_第4页
第4页 / 共51页
Linux的进程管理(一).ppt_第5页
第5页 / 共51页
点击查看更多>>
资源描述

《Linux的进程管理(一).ppt》由会员分享,可在线阅读,更多相关《Linux的进程管理(一).ppt(51页珍藏版)》请在三一办公上搜索。

1、Linux进程控制,2,主要内容,进程、线程和轻量级进程的概念进程描述符进程状态如何标识一个进程进程内核栈进程间的关系与进程创建相关的系统调用,3,进程、线程和轻量级进程,进程是程序执行的一个实例,是有限状态机的一次迁移过程。进程和程序的区别:动态与静止;多对一进程是资源分配的实体,这些资源包括:PID、task_struct、独立的内存地址空间、打开的文件描述符、信号处理函数对应表、挂起的信号等。线程是进程内一个独立的执行线路,是CPU调度的实体。线程共享所属进程的资源,但也有私有资源:栈、CPU寄存器状态、CPU时间片、优先级、线程局部存储TLS在Linux下,线程是利用轻量级进程机制实现

2、的。多个轻量级进程共享同一套资源(同一内存空间),但具有不同的栈和CPU寄存器状态。,4,进程描述符task_struct,进程描述符与进程一一对应,记录了与进程相关的所有信息进程描述符一般较大,(32位机1.7KB)创建进程描述符时使用了SLAB分配器,5,进程描述符task_struct,Linux2.6进程的状态,include/linux/sched.h,2023/7/7,Linux操作系统分析,7/65,进程状态转换图,EXIT_ZOMBIE或者EXIT_DEAD或者TASK_DEAD,如何标识一个进程,使用进程描述符地址进程和进程描述符之间有非常严格的一一对应关系,使得用32位进程

3、描述符地址标识进程非常方便使用PID(Process ID,PID)每个进程的PID都存放在进程描述符的pid域中,进程的PID,进程的pid字段,Pid最大值,参见kernel/pid.c,顺序使用&循环使用,include/linux/types.h,include/asm-XXX/posix_typesYYY.h,include/linux/threads.h,10,如何获得一个空闲的PID,32位机上,PID最大为32767为了循环使用PID编号,内核定义了一个pidmap_array位图,pidmap_array包含32768个位,刚好放到一个页框中。alloc_pid是如何实现的?

4、(last_pid变量),11,如何由PID获得对应的进程描述符,如何实现find_task_by_pid(nr)?pidhash table(固定数组,一般占4个页框,2048个表项),12,struct pid,struct pid_link int nr;/pid的数值 struct hlist_node pid_chain;struct list_head pid_list;struct task_struct struct pid_link pids4;,13,如何由PID获得对应的进程描述符,14/65,进程和进程的内核堆栈,Linux为每个进程分配一个8KB大小的内存区域,用于存

5、放该进程两个不同的数据结构:Thread_info进程的内核态堆栈进程处于内核态时使用,不同于用户态堆栈内核控制路径所用的堆栈很少,因此对栈和Thread_info来说,8KB足够了,Thread_info,15,用户态到内核态的切换,用户态和内核态的区别?从用户态切换到内核态的3种方式:系统调用:int 80 或 sysinter中断异常从用户态切换到内核态后:进程上下文(主要指页表)不切换CPU自动切换到当前进程对应的内核态堆栈工作CPU自动将用户态的寄存器状态和返回地址存放到内核栈,Thread_union,C语言允许用如下的一个union结构来方便的表示这样的一个混合体,thread_

6、info由体系结构相关部分定义阅读include/asm-x86/thread_info.h 以及include/asm-x86/thread_info_32.h,include/linux/sched.h,Current宏的使用,Current宏可以看成当前进程的进程描述符指针,在内核中直接使用举例:比如current-pid返回在CPU上正在执行的进程的PID,current宏的实现:#define get_current()(current_thread_info()-task)#define current get_current()current_thread_info的汇编代码是:

7、movl$-THREAD_SIZE,%eax;andl%esp,%eax其中#define THREAD_SIZE(2*PAGE_SIZE),21,进程间的关系,父子关系:parent,real_parent,children兄弟关系:sibling线程组关系:tgid,group_leader,thread_group进程组关系:signal-pgrp会话组关系:signal-session被调试关系:ptrace_children,ptrace_list系统中所有进程的task_struct被串成一个双向循环链表,22,进程间的关系,进程启动,23,手工启动前台启动:shell中输入命令:

8、program后台启动:shell中输入命令:program&调度启动利用at命令在指定时刻启动利用cron命令定期启动,进程管理相关命令,24,25,在程序中创建与终止进程,进程的创建和执行:Linux中进程的创建进程被分解到两个单独的函数中取执行:fork()和exec函数族。首先,fork()通过拷贝当前进程创建一个子进程,子进程与父进程的区别仅仅在于不同的PID、PPID和某些资源及统计量。exec函数族负责读取可执行文件并将其载入地址空间开始运行。进程的终止:进程终结也需要做很多繁琐的收尾工作,系统必须保证进程所占用的资源回收,并通知父进程。Linux首先把终止的进程设置为僵尸状态,

9、这个时候,进程无法投入运行了,它的存在只为父进程提供信息,申请死亡。父进程得到信息后,开始调用wait函数族,最终赐死子进程,子进程占用的所有资源被全部释放。,fork函数,fork()fork()函数用于从已存在的进程中创建一个新进程。新进程称为子进程,而原进程称为父进程。使用fork()函数得到的子进程是父进程的一个复制品,它从父进程处继承了整个进程的地址空间,包括进程上下文、代码段、进程堆栈、内存信息、打开的文件描述符、信号控制设定、进程优先级、进程组号、当前工作目录、根目录、资源限制和控制终端等,而子进程所独有的只有它的进程号、资源使用和计时器等。fork()函数语法:,fork的另一

10、个例子,int main()int var;pid_t pid;var=88;if(pid=fork()0)printf(fork errorn);else if(pid=0)var+;else sleep(2);printf(pid=%d,var=%dn,getpid(),var);return 0;,关于fork的两个问题,连续调用3次fork,共可产生多少个进程?下面的程序一共输出多少个“-”?#include#include#include int main(void)int i;for(i=0;i2;i+)fork();printf(-);return 0;,子进程复制了父进程的哪些

11、资源?,用户ID、用户组ID、进程组ID、会话ID当前工作目录、根目录、环境变量文件访问权限、资源访问权限信号屏蔽位打开的文件描述符进程地址空间(数据段、代码段、堆栈段),Fork函数的应用逻辑孙悟空逻辑,int main()./遇到两个需要并行执行的任务:任务1和任务2pid=fork();/分身术if(pid=0)/子进程处理任务1else/父进程处理任务2return 0;,Fork函数应用例1,int main()int fd1=open(“data_file1”,);int fd2=open(“data_file2”,);pid_t pid;if(pid=fork()=0)close

12、(fd2);read(fd1,buffer,len);/处理文件1的数据 else close(fd1);read(fd2,buffer,len);/处理文件2的数据,Windows创建进程APICreateProcess,BOOL CreateProcess(LPCTSTR lpApplicationName,/新进程将要使用的可执行文件的名字(路径)LPTSTR lpCommandLine,/递给新进程的命令行字符串 LPSECURITY_ATTRIBUTES lpProcessAttributes。LPSECURITY_ATTRIBUTES lpThreadAttributes,BOOL

13、 bInheritHandles,DWORD dwCreationFlags,LPVOID lpEnvironment,LPCTSTR lpCurrentDirectory,LPSTARTUPINFO lpStartupInfo,LPPROCESS_INFORMATION lpProcessInformation);,CreateProcess的应用逻辑黑社会逻辑,Main.exe:主控程序,黑社会BossA.exe:专门处理任务A的程序,黑社会小弟B.exe:专门处理任务A的程序,黑社会小弟int main()./遇到两个需要并行执行的任务:任务A和任务B CreateProcess(“A.

14、exe”,);/叫个小弟来处理任务A CreateProcess(“B.exe”,);/叫个小弟来处理任务B./自己继续享受生活,exec函数,exec函数用于创建一个新的进程,新进程以另一个可执行程序为执行脚本。exec创建的新进程“占用了”原进程的绝大部分资源,进程地址空间中装入了新的可执行程序。exec执行成功之后,原进程就“消失了”。#include int execl(const char*path,const char*arg,.)参数path:可执行文件的路径和名字构成的字符串arg:新程序的命令行参数1execl是一个不定参数函数,还可以传入多个命令行参数,最后一个参数必须是N

15、ULL。返回值:-1 表示出错,exec函数的例子1,#include int main(int argc,char*argv)if(execl(/bin/echo,echo,executed by execl,NULL)0)perror(Err on execl);,exec函数的例子2,如果还想保留父进程怎么办?#include int main(int argc,char*argv)if(fork()=0)if(execl(/bin/echo,echo,executed by execl,NULL)0)perror(Err on execl);/父进程做其他事情 return 0;,ex

16、ec函数族,exec函数族使用区别,exec函数族使用区别查找方式表中的前四个函数的查找方式都是完整的文件目录路径,而最后两个函数(以p结尾的函数)可以只给出文件名,系统就会自动从环境变量“$PATH”所指出的路径中进行查找。参数传递方式两种方式:逐个列举、将所有参数整体构造指针数组传递以函数名的第五位字母来区分的,字母为“l”(list)的表示逐个列举的方式,其语法为char*arg;字母为“v”(vertor)的表示将所有参数整体构造指针数组传递,其语法为*const argv环境变量exec函数族可以默认系统的环境变量,也可以传入指定的环境变量。这里,以“e”(Enviromen)结尾的

17、两个函数execle、execve就可以在envp中指定当前进程所使用的环境变量,exec与fork配合使用的效率问题,在Unix时代exec经常与fork配合使用,但这样做了大量的无用功,效率低下(为什么?)。为了解决该问题,在Unix时代创建了vfork函数与exec配合。vfork函数不复制父进程的资源,而是共享父进程资源,直到碰到exec函数才开始复制父进程的部分资源(不包括进程地址空间)。在Linux时代,fork函数实现中引入了“写时拷贝Copy On Write”技术,fork+exec的配合效率也很高。Linux时代,vfork几乎没有存在的必要,只被用在极少数场合。,vfor

18、k函数,vfork()其功能类似于fork(),但是有以下两点显著的不同:vfork()不同于fork(),它没有复制自己的进程地址空间,而是共享父进程的,所以,子进程的改变也会引起父进程的改变vfork()创建后子进程总是立即优先于父进程执行的,在子进程exec或者exit后,才会执行父进程。vfork()函数语法:pid_t vfork(void);,clone函数,int clone(int(*fn)(void*),void*child_stack,int flags,void*arg);clone可以让你有选择性的继承父进程的资源,你可以选择想vfork一样和父进程共享一个虚存空间,从

19、而使创造的是线程,你也可以不和父进程共享,你甚至可以选择创造出来的进程和父进程不再是父子关系,而是兄弟关系。clone还可以为新进程指定EIP的值(令EIP指向fn指向的函数)fork的子进程和父进程不共享任何资源。Vfork=clone(EIP,ESP,CLONE_VFORK|CLONE_VM,0);,clone函数,CLONE_PARENT 创建的子进程的父进程是调用者的父进程,新进程与创建它的进程成了“兄弟”而不是“父子”CLONE_FS 子进程与父进程共享相同的文件系统,包括root、当前目录、umask CLONE_FILES 子进程与父进程共享相同的文件描述符(file descr

20、iptor)表 CLONE_NEWNS 在新的namespace启动子进程,namespace描述了进程的文件hierarchy CLONE_SIGHAND 子进程与父进程共享相同的信号处理(signal handler)表 CLONE_PTRACE 若父进程被trace,子进程也被trace CLONE_VFORK 父进程被挂起,直至子进程释放虚拟内存资源 CLONE_VM 子进程与父进程运行于相同的内存空间 CLONE_PID 子进程在创建时PID与父进程一致 CLONE_THREAD Linux 2.4中增加以支持POSIX线程标准,子进程与父进程共享相同的线程群,44,exit()和_

21、exit()函数,exit()和_exit()exit()和_exit()函数都是用来终止进程的。当程序执行到exit()或_exit()时,进程会无条件地停止剩下的所有操作,清除包括各种数据结构,并终止本进程的运行。int atexit(void(*function)(void);function是一个函数指针,指向程序退出时候调用的一个回调函数。利用该函数程序能够在最终关闭之前提供一个或者多个运行的清理函数atexit用于注册一个或多个退出函数,45,exit()和_exit()的执行过程,exit()和_exit()的执行过程,46,exit()和_exit()的区别,exit()和_e

22、xit()的区别_exit()函数的作用是直接使进程停止运行,清除其使用的内存空间,并销毁其在内核中的各种数据结构;exit()函数则在这些基础上作了一些包装,在执行退出之前加了若干道工序。exit()函数与_exit()函数最大的区别就在于exit()函数在终止当前进程之前要检查该进程打开过哪些文件,把文件缓冲区中的内容写回文件,就是图中的“清理I/O缓冲”一项。“标准文件I/O”,exit()和_exit()函数,exit()和_exit函数语法:,僵尸进程,僵尸进程产生条件子进程执行完毕;父进程没有回收其状态;子进程退出前会向父进程发送SIGCHLD信号父进程用wait和waitpid回收,49,wait()和waitpid(),wait()和waitpid()wait()函数是用于使父进程(也就是调用wait()的进程)阻塞,直到一个子进程结束或者该进程接到了一个指定的信号为止。如果该父进程没有子进程或者他的子进程已经结束,则wait()就会立即返回。waitpid()的作用和wait()一样,但它并不一定要等待第一个终止的子进程,它还有若干选项,如可提供一个非阻塞版本的wait()功能。wait函数语法:,50,wait()和waitpid(),wait()和waitpid()waitpid函数语法:,51,wait()和waitpid()waitpid实例:,

展开阅读全文
相关资源
猜你喜欢
相关搜索

当前位置:首页 > 生活休闲 > 在线阅读


备案号:宁ICP备20000045号-2

经营许可证:宁B2-20210002

宁公网安备 64010402000987号