




版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领
文档简介
Linux进程和线程编程1、Linux中的进程相关概念2、Linux中的进程的创建3、Linux中的进程的管理和守护进程6.1进程的概述时间和空间是计算机的两个概念,操作系统将者两个概念实现为文件和进程。进程是一个可以独立的可有OS调度的活动。进程是一个抽象实体,当它执行的时候需要OS分配资源。进程是一个正在执行的程序。进程是一个程序的一次执行。进程是一个具有一定独立功能的程序关于某个数据集合的一次运行活动。它是操作系统动态执行的基本单元,在传统的操作系统中,进程既是基本的分配单元,也是基本的执行单元6.1进程的概述进程的概念主要有两点:第一,进程是一个实体。每一个进程都有它自己的地址空间,一般情况下,包括文本区域(textregion)、数据区域(dataregion)和堆栈(stackregion)。文本区域存储处理器执行的代码;数据区域存储变量和进程执行期间使用的动态分配的内存;堆栈区域存储着活动过程调用的指令和本地变量。第二,进程是一个“执行中的程序”。程序是一个没有生命的实体,只有处理器赋予程序生命时,它才能成为一个活动的实体,我们称其为进程。进程是操作系统中最基本、重要的概念。是多道程序系统出现后,为了刻画系统内部出现的动态情况,描述系统内部各道程序的活动规律引进的一个概念,所有多道程序设计操作系统都建立在进程的基础上。原因原因原因原因操作系统引入进程的概念的原因:从理论角度看,是对正在运行的程序过程的抽象;从实现角度看,是一种数据结构,目的在于清晰地刻划动态系统的内在规律,有效管理和调度进入计算机系统主存储器运行的程序。6.1.1进程的描述进程的种类交互进程:由一个Shell启动的进程,交互进程既可以在前台运行,也可以在后台运行。
批处理进程:这种进程和终端没有联系,是一个进程序列。监控进程:也称守护进程,Linux系统启动是启动的进程,并在后台运行。进程不但包括程序指令和数据,还包括程序计数器和CPU的所有寄存器及其存储临时数据的进程堆栈。Linux是一个多进程OS,其他进程必须等到当前正在执行的进程交出CPU的控制权后才能被内核调度执行。当正在运行的进程等待其他系统资源时,linux内核获得CPU的控制权,并将CPU分配给其他正在等待的进程,内核中的调度算法决定将CPU分配给那个进程。内存是计算机的敏感资源,熟练掌握对内存的操作是一个程序员的必备素质。数据的内部存储方式:大小端法在c中,不同的数据类型占用的空间是不同的,例如char类型占用1个字节,而int占用4个字节高785634低12345612786.1.1进程的描述-进程内存管理-数据内部存储时间和空间是计算机的两个基本的概念,操作系统将这两个概念实现未进程和文件,。进程ID是一个进程的基本属性,其作用类似与人的身份证号,根据进程ID用户可以精确的定位一个进程,一个标识符对应于一个进程,,多个进程标识符可以对应于一个程序。进程标识符的类型是pit_t,他是一个无符号整数。进程标识符1进程标识符2进程标识符3进程1进程2进程3程序2程序16.1.1进程的描述-进程标识符进程ID使用PS查看当前进程ps-u[用户名]
第一列是进程id最后一列是对应的程序名称6.1.1进程的描述-进程标识符进程IDLinux操作系统包括三种不同类型的进程,每种进程都有自己的特点和属性。交互进程——由一个shell启动的进程。交互进程既可以在前台运行,也可以在后台运行(人机交互)。批处理进程——这种进程和终端没有联系,是一个进程序列(多个进程)。监控进程(也称守护进程)——Linux系统启动时启动的进程,并在后台运行。6.1.1进程的描述-Linux进程分类运行状态:此时进程或者正在运行或者准备运行等待状态:此时进程在等待一个事件的发生或者某种系统资源停止状态:此时进程已经被终止死亡状态:这是一个停止的进程,但是在进程向量数组中占有一个task_struct结构R(TASK_RUNNING),可执行状态S(TASK_INTERRUPTIBLE),可中断的睡眠状态。D(TASK_UNINTERRUPTIBLE),不可中断的睡眠状态。s进程的领导者+前台进程6.2.1Linux进程运行状态每一个进程有6个重要的ID,分别是进程ID、父进程ID、有效用户ID、有小组ID、实际用户ID和实际组ID。这六个ID保存在内核中的数据结构中,有些时候用户程序需要用到这些ID。例如在/proc文件系统下每个进程有一个目录,里面存放进程的相关信息,当进程要读取这些文件时,应该先得到当前进程的ID才能确定进入那一个进程相关的子目录,由于这些ID存储在内核之中,因此linux提供一组专门的接口函数访问这些ID值。Linux环境下使用getpid和getppid函数获得进程和父进程的ID,其函数原型如下:#include<unistd.h>Pid_tgetpid(void)pid_tgetppid(void)函数成功返回进程的id,失败返回-1,6.2.1Linux进程标识符Linux环境下使用getuid和geteuid函数获得进程用户ID,其函数原型如下:#include<unistd.h>uid_tgetuid(void)uid_tgeteuid(void)函数成功返回进程的用户id,失败返回-1.Linux环境下使用getgid和getegid函数获得进程用户组ID,其函数原型如下:#include<unistd.h>gid_tgetgid(void)gid_tgetegid(void)函数成功返回进程的用户id,失败返回-1,Pid_t类型参看/usr/include/bits/types.h实际就是int类型6.2.1Linux进程标识符每6.2.1Linux进程标识符启动进程和调度进程1手动启动:用户直接输入shell命令后回车直接启动进程前台启动:用户输入一个shell命令后按回车就启动给一个前台进程后台启动:在shell命令后加入一个“&”符号再按回车键就可以启动一个后台作业。6.2.2Linux进程标识符启动进程的前后台切换1bg命令(background)格式bg[作业号]功能:将前台作业切换到后台运行,若没有指定的作业则将当前作业切换到后台例如使用vi编辑文件f1然后用ctrl+Z组合挂起vi再切换到后台6.2.2Linux进程进程前后台切换3.Fg挂起程序作用:fg命令使一个被挂起的进程在前台执行。格式:fg-[job-spec][job-spec]:后台任务号码。说明:fg命令和bg命令是相对应的。如果想查看后台程序运行情况,可以使用fg命令把它调回前台查看。bg命令可以使多个进程放到后台中执行。6.2.2Linux进程进程命令作用:ps命令主要查看系统中进程的状态。格式:ps[选项]主要选项如下。-A:显示系统中所有进程的信息。-e:显示所有进程的信息。-f:显示进程的所有信息。-l:以长格式显示进程信息。-r:只显示正在运行的进程。-u:显示面向用户的格式(包括用户名、CPU及内存使用情况等信息)。-x:显示所有非控制终端上的进程信息。-p:显示由进程ID指定的进程的信息。-t:显示指定终端上的进程的信息。6.2.2Linux进程进程命令-ps说明:要对进程进行监测和控制,首先要了解当前进程的情况,也就是需要查看当前进程。ps命令就是最基本、也是非常强大的进程查看命令。根据显示的信息可以确定哪个进程正在运行、哪个进程被挂起、进程已运行了多久、进程正在使用的资源、进程的相对优先级,以及进程的标志号(PID)。所有这些信息对用户都很有用,对于系统管理员来说更为重要。使用"ps-aux"命令可以获得终端上所有用户的有关进程的所有信息,下面结合图4-8讲解进程的基本信息6.2.2Linux进程进程命令-psUSER表示启动进程用户。PID表示进程标志号。%CPU表示运行该进程占用CPU的时间与该进程总的运行时间的比例。%MEM表示该进程占用内存和总内存的比例。VSZ表示占用的虚拟内存大小,以KB为单位。RSS为进程占用的物理内存值,以KB为单位。TTY表示该进程建立时所对应的终端,"?"表示该进程不占用终端。STAT表示进程的运行状态,包括以下几种代码:D,不可中断的睡眠;R,就绪(在可运行队列中);S,睡眠;T,被跟踪或停止;Z,终止(僵死)的进程,Z不存在,但暂时无法消除;W,没有足够的内存分页可分配;<高优先序的进程;N,低优先序的进程;L,有内存分页分配并锁在内存体内(实时系统或I/O)。START为进程开始时间。TIME为执行的时间。COMMAND是对应的命令名。6.2.2Linux进程进程命令-pstop命令显示进程top命令用来显示系统当前的进程状况。格式:top[选项]主要选项如下。d:指定更新的间隔,以秒计算。q:没有任何延迟的更新。如果使用者有超级用户,则top命令将会以最高的优先序执行。c:显示进程完整的路径与名称。S:累积模式,会将已完成或消失的子进程的CPU时间累积起来。s:安全模式。i:不显示任何闲置(Idle)或无用(Zombie)的进程。n:显示更新的次数,完成后将会退出top。6.2.2Linux进程进程命令-topnice命令改变权限优先级作用:nice命令可以改变程序执行的优先权等级。格式:nice[-n<优先等级>][--help][--version][命令]主要选项如下。-n<优先等级>或-<优先等级>或--adjustment=<优先等级>:设置欲执行的命令的优先权等级。等级的范围从-20~19,其中-20为最高,19为最低。--help:在线帮助。说明:应用程序优先权值的范围从-20~19,数字越小,优先权就越高。一般情况下,普通应用程序的优先权值(CPU使用权值)都是0,如果让常用程序拥有较高的优先权等级,自然启动和运行速度都会快些。需要注意的是普通用户只能在0~19之间调整应用程序的优先权值,只有超级用户有权调整更高的优先权值(从-20~19)。例如:nice–n1ls>1.txt6.2.2Linux进程进程命令-nicerenice命令修改优先级作用:renice命令允许用户修改一个正在运行的进程的优先权。格式:renicepriority[[-p]pids][[-g]pgrps][[-u]users]主要选项如下。priority:优先等级-ppids:改变该程序的优先权等级,此参数为预设值。-gpgrps:使用程序群组名称,修改所有隶属于该程序群组的程序的优先权。-uuser:指定用户名称,修改所有隶属于该用户的程序的优先权。说明:renice命令可重新调整正在执行的程序的优先权等级。默认是以程序识别码指定程序,调整其优先权,也可以指定程序群组或用户名称调整优先权等级,并修改所有隶属于该程序群组或用户的程序的优先权。等级范围从-20~19,只有超级用户可以改变其他用户程序的优先权和设置负数等级。普通用户只能对自己所有的进程使用renice命令。应用实例如下:将进程PID为987及32的进程与进程拥有者为daemon及root的优先级别号加1:#renice+1987–udaemonroot–p326.2.2Linux进程进程命令-Renicesleep命令暂停进程作用:sleep命令的功能是使进程暂停执行一段时间。格式:sleepnumber[选项]主要选项如下。number:时间长度,后面可接s、m、h或d。s:以秒为单位。m:以分钟为单位。h:以小时为单位。d:以天为单位。说明:如果没有指定时间,以秒为单位。此命令大多用于shell程序设计中,使两条命令执行之间停顿指定的时间。应用实例如下。下面的命令使进程先暂停60秒,然后查看哪个用户登录到系统中:#sleep60;who6.2.2Linux进程进程命令-sleepkill命令杀掉进程作用:kill命令终止一个进程。格式:kill[-ssignal|-p][-a]pid…kill-l[signal]主要选项如下。-s:指定发送的信号。-p:模拟发送信号。-l:指定信号的名称列表。pid:要终止的进程的ID号。signal:表示信号。6.2.2Linux进程进程命令-kill说明:kill可将指定的信息送至程序。预设的信息为SIGTERM(15),可将指定程序终止。若仍无法终止该程序,可使用SIGKILL(9)信息尝试强制删除程序。kill命令的工作原理是,向Linux系统的内核发送一个系统操作信号和某个程序的进程标志号,然后系统内核就可以对进程标志号指定的进程进行操作。当需要中断一个前台进程的时候,通常使用Ctrl+C组合键;但是对于一个后台进程,就不是一个组合键所能解决的了,这时就必须使用kill命令。应用实例如下。命令执行过程如果出错,用户可用"kill"来结束任务。对于在后台运行的进程,可以使用kill命令终止:$kill-s918276.2.2Linux进程进程命令-kill1.at命令:定时运行命令作用:at命令在指定时刻执行指定的命令序列。#at2:05tomorrowat>/home/mj/airplane>/home/mj/air-safeat>Ctrl+D2crontab命令作用:crontab命令用于安装、删除或者列出用于驱动cron后台进程的任务表。然后,该配置由cron守护进程在设定的时间执行。格式:crontab[-uuser]文件6.2.2Linux进程进程命令-atfork()–创建一个新进程Wake()唤醒一个进程Schedule()进程调度函数Exit()退出进程6.3.1Linux进程进程函数运行态拥有CPU进就绪态不可中断进就绪态可中断僵尸态停止态fork()wake()资源到位或者收到信号wake()资源到位schedute()进程调度sleep_uninterruptible()深度睡眠等待资源Sleep_interruptible()浅度睡眠等待资源exit()收到SIG_KILL或者SIGCONT_wake()6.3.2Linux进程状态睡眠进程可以被程序再次的唤醒,而僵死进程不会被任何程序唤醒,只能通过命令kill掉深度睡眠和浅度睡眠进程得到它需要的资源被唤醒,通过schedule()进入执行态,深度睡眠的进程不能被信号或者定时中断唤醒,只有它申请的资源又有效是才能被唤醒。Linux中,仅等待CPU时间的进程称为就绪进程,它们被放置在一个运行队列中,一个就绪进程的状态标志位为TASK_RUNNING。一旦一个运行中的进程时间片用完,Linux内核的调度器会剥夺这个进程对CPU的控制权,并且从运行队列中选择一个合适的进程投入运行。
当然,一个进程也可以主动释放CPU的控制权。函数schedule()是一个调度函数,它可以被一个进程主动调用,从而调度其它进程占用CPU。一旦这个主动放弃CPU的进程被重新调度占用CPU,那么它将从上次停止执行的位置开始执行,也就是说它将从调用schedule()的下一行代码处开始执行。
有时候,进程需要等待直到某个特定的事件发生,例如设备初始化完成、I/O操作完成或定时器到时等。在这种情况下,进程则必须从运行队列移出,加入到一个等待队列中,这个时候进程就进入了睡眠状态。6.3.2Linux进程状态Linux中,仅等待CPU时间的进程称为就绪进程,它们被放置在一个运行队列中,一个就绪进程的状态标志位为TASK_RUNNING。一旦一个运行中的进程时间片用完,Linux内核的调度器会剥夺这个进程对CPU的控制权,并且从运行队列中选择一个合适的进程投入运行。
当然,一个进程也可以主动释放CPU的控制权。函数schedule()是一个调度函数,它可以被一个进程主动调用,从而调度其它进程占用CPU。一旦这个主动放弃CPU的进程被重新调度占用CPU,那么它将从上次停止执行的位置开始执行,也就是说它将从调用schedule()的下一行代码处开始执行。
有时候,进程需要等待直到某个特定的事件发生,例如设备初始化完成、I/O操作完成或定时器到时等。在这种情况下,进程则必须从运行队列移出,加入到一个等待队列中,这个时候进程就进入了睡眠状态。6.3.2Linux进程状态父子进程:除了PID号为0号进程以外的其他进程都是有其他进程创建的,创建进程的进程是父进程,被创建的进程称为子进程。进程是系统中执行的基本单位,liunx系统允许任何而一个用户创建一个子进程。创建之后,子进程存在系统之中,并且独立于父进程。该子进程可以接受系统调度,可以分配得到系统资源,系统可以检测到他的存在,并且赋予他的父进程同样的权利。Linux使用fork函数创建一个新的进程,其函数原型如下:#include<unistd.h>Pid_tfork(void)6.4.1Linux进程系统调用-创建进程Fork函数不需要参数,返回值是一个进程ID,返回值分为3种。对于父进程,fork函数返回新创建子进程的ID对于子进程,fork函数返回0如果出错则返回-1Fork函数会创建一个新的进程,并从内核中未此进程得到一个新的ID,之后未这个新进程分配内存空间,并将父进程的进程空间代码的内容复制到子进程的进程空间中,包括父进程的数据段和堆栈段,并且和父进程共享代码段。这时系统各种又多了一个进程,这个进程和父进程一模一样,两个进程都要接受系统的调度。6.4.1Linux进程系统调用-创建进程fork函数6.4.1Linux进程系统调用-创建进程fork函数子进程完全复制了父进程的地址空间代内容,包括对战段和数据库的内容,子进程并没有复制代码段,而是和父进程公用代码段。Fork函数的出错情况:Fork有两种情况返回-1系统中已有太多的进程存在了调用fork函数的用户进程太多了一般情况下系统会对进程数目进行限制,如果操作系统对其不加限制,则用户可以利用这一漏洞攻击系统父进程的数据段父进程的代码段系统中的其他数据子进程的数据段子进程的代码段指向父进程的代码段6.4.1Linux进程系统调用-创建进程fork函数由于fork函数完整的拷贝了父进程的整个地址空间,因此,执行速度比较慢,为了加快fork的执行速度,在有些liunx中使用vfork函数。Vfork函数产生的子进程和父进程完全共享地址空间,包括代码段、数据段和堆栈段,子进程对这些共享资源所做的修改,可以影响到父进程Vfork函数产生的子进程一定比父进程先运行,也就是说父进程调用了vfork函数后会等待子进程运行后再运行。Vfork函数创建新的进程,但他不产生父进程的副本,他通过允许父子进程可访问相同物理内存从而为装了对进程地址的真实拷贝,当子进程需要改变内存中的数据时才会拷贝父进程。这就是著名的“写操作时拷贝”copy-on-write技术6.4.1Linux进程系统调用-创建进程vfork函数上面讲了进程的fork函数,很多人有疑问既然所有的进程都是fork创建的,那么linux所有的进程不就几乎全部一样吗,而且就我们的常识而言,当我们执行一个程序时,新产生的进程内容就因该是程序的内容才对。Linux环境使用exec函数执行一个新程序,该函数在文件系统中搜索指定的路径文件,并将该文件内容复制到调用的exec函数地址空间,取代原来的进程内容。Exec函数提供了一个在进程中启动另一个程序的方法他可以根据指定的文件名和目录找到可执行代码,并用它来取代原调用进程的数据段代码段和堆栈段,在执行之后,远调用进程的内容中除了进程号以外,其他全部被新的进程替换了。可执行文件可以是二进制文件也可以是liunx下的脚本文件。6.4.2Linux进程系统调用-exec函数在什么情况下使用exec函数当有进程认为自己不能再为系统和用户作出任何新贡献了,就可以调用任何exec函数族,让自己以新的面貌重生。如果一个进程想执行另一程序,它就可以调用fork函数新建一个进程,然后执行任何一个exec函数,这样看起来就像通过执行应用程序而产生了一个新进程一样。6.4.2Linux进程系统调用-exec函数所需头文件#include<unistd.h>intexecl(constchar*path,constchar*arg,...);intexeclp(constchar*file,constchar*arg,...);intexecle(constchar*path,constchar*arg,...,char*constenvp[]);intexecv(constchar*path,char*constargv[]);intexecvp(constchar*file,char*constargv[]);intexecve(constchar*path,char*constargv[],char*constenvp[]);其中只有execve是真正意义上的系统调用,其它都是在此基础上经过包装的库函数。exec函数族的函数执行成功后不会返回,因为调用进程的实体,包括代码段,数据段和堆栈等都已经被新的内容取代,只留下进程ID等一些表面上的信息仍保持原样,颇有些神似"三十六计"中的"金蝉脱壳"。看上去还是旧的躯壳,却已经注入了新的灵魂。只有调用失败了,它们才会返回一个-1,从原程序的调用点接着往下执行。6.4.2Linux进程系统调用-exec函数Execl的第一个参数是包含路劲的可执行文件,后面是参数列表,列表的第一个为命令path,接着为参数列表,最后必须以null结束。Execlp的第一个参数可以使用绝对路径或者是相对路径Excele最后包含指向一个自定义环境变量列表的指针,此列表必须以null结束。Execv,v表示path后面接受的是一个向量,即指向一个参数列表的指针,注意这个列表的最后一项必须是nullExecvepath后面的接受一个参数列表向量,并可以指定一个环境变量列表向量Execvp,第一个参数可以使用相对或者绝对路径,v表示后面接受一个参数列表向量。6.4.2Linux进程系统调用-exec函数对于l表示list,说明执行程序的命令参数以列表的方式提供,并且用null结束。参数的个数没有限制。如下:Char*arg0,Char*arg1,Char*arg2,nullV表示所有的参数以指针数组方式给出,其语法为*constargv[],这个数组的每一行是一个命令参数。E表示传递给新程序的环境变量列表,这个列表是一个数组,数组的每一行表示一个环境变量,如果没有显示的说明环境变量则新程序继承父进程的环境变量。P表示第一参数不是完整的路径名,这是就要从环境变量中读取环境变量参数组合成一个完整的路径名。那么exec函数就会匹配bin/filename、usr/bin/filename直到找到一个正确路径,就将该文件加载到内存执行,如果该文件不存在则,exec函数出错。6.4.2Linux进程系统调用-exec函数Exec函数调用hello程序使用exec函数调用当前目录下的hello程序Exec函数调用ps–ef命令Exec函数调用hello程序带参数的程序执行./helloc1helloworldLinux进程标识符#include<unistd.h>
intmain(intargc,char*argv[])
{
char*envp[]={"PATH=/tmp","USER=lei","STATUS=testing",NULL};
char*argv_execv[]={"echo","excutedbyexecv",NULL};
char*argv_execvp[]={"echo","executedbyexecvp",NULL};
char*argv_execve[]={"env",NULL};
if(fork()==0){
if(execl("/bin/echo","echo","executedbyexecl",NULL)<0)
perror("Erronexecl");
}
if(fork()==0){
if(execlp("echo","echo","executedbyexeclp",NULL)<0)
perror("Erronexeclp");
}
if(fork()==0){
if(execle("/usr/bin/env","env",NULL,envp)<0)
perror("Erronexecle");
}
if(fork()==0){
if(execv("/bin/echo",argv_execv)<0)
perror("Erronexecv");
}
if(fork()==0){
if(execvp("echo",argv_execvp)<0)
perror("Erronexecvp");
}
if(fork()==0){
if(execve("/usr/bin/env",argv_execve,envp)<0)
perror("Erronexecve");
}
}Exec函数注意事项在使用exec函数时一定要加上错误判断语句最常见的错误有找不到制定的文件或者路径在使用argv和envp时忘记用NULL结束没有对应可执行文件的运行权限退出进程exit函数当一个进程需要退出时,需要调用退出函数这个退出函数会深入到内核注销掉进程的内核数据结构,并且释放进程资源。Linux环境下使用exit函数退出进程,其函数原型如下#include<stdlib.h>Voidexit(intstatus)intstatus表示退出状态,这一状态是一个整形值,在shell中可以查看这个值。使用echo$?C程序中的return语句被翻译成exit语句如return1-exit(1)exit和_exit区别Exit是一个标准的库函数,其内部封装了linux的系统调用函数_exit,两者的主要区别在于exit函数会在用户空间做一些善后工作,如清理用户的I/O缓冲区,将其内容写入磁盘文件,之后在释放用户进程的地址空间,而_exit函数直接进入内核释放用户的地址空间,所有用户空间的缓冲区内容都将丢失。在liunx标准函数库中,有一套称为“高级I/O”的函数,我们熟知的printf()fopen()fread()fwrite()都在此列,他们被称为缓冲IO函数,其特征是每次对应打开文件都会在内存中有一片缓冲区,每次度文件时会读取若干条记录,这样下次读文件就可以直接从缓冲去区中读取,每次写文件件时也是先写到缓冲区,等满足一定条件在将缓冲区中的数据一次性写入文件,这样可以大大提到文件的读写速度。但是当我们使用_exit函数时就会产生问题,因为改函数直到内核接释放进程,就会产生缓冲区数据丢失的情况。exit和_exit区别进程运行调用退出函数清理I/O缓冲区调用exit系统调用进程终止运行_exit()exit()_exit函数直接清除进程的内存空间,并销毁其在内核中的各种数据结构,exit函数在调用exit系统调用之前要检查文件的打开情况,吧文件的缓冲区中的内容回写到文件,对应与图中“清理缓冲区”一项exit和_exit区别说明:在一个进程调用了exit之后,该进程并不会马上完全小时,而是留下一个称为僵尸进程(Zombie)的数据结构。僵尸进程是一种非常特殊的进程,它几乎已经放弃了所有的内存空间,没有任何可执行代码,也不能被调度,仅仅在进程列表中保留一个位置,记载该进程的退出状态等信息供其它进程收集,除此之外,僵尸进程不再占有任何内存空间。僵尸进程每个进程都有一个父进程,当进程退出时,其退出状态可以被父进程得到,父进程调用wait函数取得子进程的退出状态信息。这些退出状态信息保存在内核中,占用很少一块内存空间,当子进程退出时,这些信息仍然被保存在内核中,子进程的进程ID也同样保存在系统进程里列表中,这是的进程称为僵尸进程。僵尸进程几乎放弃了所有的资源,包括地址空间,僵尸进程不能执行,因此不能被系统调度,也不会占用cpu时间,僵尸进程占用的资源是微乎其微的,僵尸进程会一直存在于系统中直到其父进程得到其结束状态信息。看起来僵尸进程好像对系统没有什么影响,但是僵尸进程会占用进程pid号,在liunx中严格限制了进程的数量,僵尸进程达到一定数量后就不能再创建新的进程。因此当父进程使用fork函数创建进程而不调用wait函数时一个个僵尸进程就产生了。创建一个僵尸进程僵尸进程上面的例子在shell中编译gcczombile.c–ozombile执行./zombile打开另一个终端输入ps–ax父进程休眠时子进程的僵尸状态Wait函数Linux下使用wait函数得到进程结束状态信息,其函数原型如下:#include<sys/wait.h>Pid_twait(int*status)调用wait函数的进程会阻塞,直到该进程的任意一个子进程结束,wait函数会取得结束进程的信息并返回该子进程的pid,子进程的结束信息保存在参数statloc所指向的内存空间中,如果该进程没有子进程则立即出错返回,返回-1,如果在调用wait函数时已经有若干个子进程结束运行了,则wait函数立即返回,但是具体取得哪一个子进程的信
温馨提示
- 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
- 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
- 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
- 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
- 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
- 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
- 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。
最新文档
- 2024-2025学年高中语文第四单元走进语言现场活动体验永不消逝的歌声训练含解析苏教版必修4
- 2024年领军高考物理一轮复习专题9.3曲线运动提高训练含解析
- 2024-2025学年高中生物课时分层作业18基因工程及其应用含解析新人教版必修2
- 第二章 问题研究 何时“蓝天”常在 教学设计 2023-2024学年高一上学期地理人教版(2019)必修第一册
- 人教版七年级上学期历史与社会教学设计:2.2.2 气象万千
- 信息技术必修1数据与计算2.3《周而复始的循环》教学设计
- 登泰山记 教学设计 2024-2025学年统编版高中语文必修上册
- 水平五田径蹲踞式起跑 第1课时教学设计-2023-2024学年高一上学期体育与健康人教版必修第一册
- 14《荷塘月色》《我与地坛》群文阅读教学设计2024-2025学年统编版高中语文必修上册
- Unit 7 教学设计 2024-2025学年人教版(2024)七年级英语上册
- 第8课《山山水水》教学设计(新人教版小学美术六年级上册)
- word 公章 模板
- 世界技能大赛PPT幻灯片课件(PPT 21页)
- Python程序设计ppt课件完整版
- T∕ZSQX 008-2020 建设工程全过程质量行为导则
- 质量管理体系基础知识培训-2016
- 《腹膜透析》ppt课件
- 甲醇催化剂说明书
- 北京课改版(2021年春修订版)数学四年级下册全册教学课件
- 汽车标准法规(课堂PPT)
- 碳硅及其化合物-讲义
评论
0/150
提交评论