2.2-2.3进程的描述进程控制讲解.ppt
文本预览下载声明
为 防止OS本身及关键数据遭到应用程序的有意或无意破坏,通常将处理机的执行状态分成系统态(管态、内核态)和用户态(目态、用户态)。 管态:特权较高,能执行一切指令,访问所有寄存器和存储区,OS在管态下运行。 目态:特权较低,仅执行规定指令,访问指定的寄存器和存储区,应用程序在目态下运行。 1.系统调用 ⑴.进程终止 格式:void exit(stat); 进程结束时使用该系统调用自我终止,并向创建它的父进程发终止信号stat。 ⑵.父进程等待子进程终止 格式1:pid_t wait( [ int *stat_addr,] 0 ); 功能:父进程使用它等待任意一个子进程终止,如果在执行wait()之前已经有一个子进程结束了,则对其做善后处理,并返回子进程的pid号,如果没有则返回-1,该进程阻塞,插入等待子进程终止的队列,当有子进程终止时被唤醒。在stat_addr中保留了子进程僵死时的终止信息(不是返回值)。 格式2:pid_t waitpid (pid_t pid, int * stat_addr, int options ); 功能:等待指定pid的子进程终止 注意:一个wait()只能用来等待一个子进程终止,如果等待多个子进程终止则需要使用多个wait()。 返回值:≥0 表示有子进程终止,其值为终止子进程的pid号。 -1 表示无子进程终止。 所用头文件: # include sys / wait.h # include sys / types.h 若父进程仅仅只是等待任意一个子进程结束,而不需要取 子进程发来的信号,则可以简单地使用 wait(0)。 注意:如果该进程没有创建自己的子进程就不能使用wait() 或waitpid(),否则系统会返回一个出错信息。 如果要取子进程执行exit()后所发来的终止信号stat,可以 使用*stat来取该变量中的值,而不能使用wait()的返回值,因 为wait()的返回值是该终止子进程的pid号。在Linux9版本 中,终止信号stat的值是子进程用exit(stat)发出的stat的值的 256倍。 2.父进程等待子进程的同步举例 利用exit()和wait()实现父进程等待子进程的同步的最简单的方法是: 在子进程结束处使用系统调用exit(0),使子进程自我终止,并发终止信号给其父进程; 在父进程中需要等待子进程结束处使用系统调用wait(0),有几个子进程就要使用几个wait(0)分别接收诸子进程的终止信号,从而实现父进程等待子进程的同步。 [例] 实现子进程先输出“B”然后父进程再输出“A”。 #includestdio.h main() { int p1; while((p1=fork())==-1); if(p10) { wait(0); //父进程等待子进程终止 putchar(A); } else { putchar(B); exit(0); //子进程向父进程发终止信号0 } } 源程序编译连接并多次运行后的结果都是子进程先输出B父进程后输出A,说明父进程等待子进程的同步关系成立: 3.父进程如何取子进程的终止信息举例[例]:父进程创建子进程p1,若p1终止时执行exit(1),父进程中使用wait(stat)取该信息,再输出*stat的值则可以看到其值为256,即1*256。由此可见,其信息的存储格式为n*256(不同的版本可能不同)。将下述程序中子进程的终止函数的参数分别置为:exit(0)、exit(1)和exit(2),然后分别编译执行3次,观察输出的结果: #includeunistd.h #includestdio.h main() { int p,*stat_addr; while((p=fork())==-1); //创建子进程 if(p==0) //子进程返回发终止信息 exit(0); //分别使用exit(0)、exit(1)、exit(2) else //父进程返回 { wait(stat_addr); //等待并取子进程终止信息 printf(%d\n,*stat_addr); //输出终止信息 exit(0); } } 运行结果: 注意:子进程用exit(status)发给父进程的status信息不是wait( )的返回值,如果使用语句x=wait(status),则x的值是终止执行的子进程的pid号。 1.问题的提出 子进程被创建时,该子进程映像中的程序是操作系统在 响应fork( )调用时,复制其父进程映像所得
显示全部