版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领
文档简介
1、 Linux操作系统上机三:Linux进程控制 1.目的(1)掌握系统调用fork(),exex(),exit()等实现进程创建;(2)掌握进程的终止方式(return、exit、_exit、abort);(3)掌握僵尸进程的产生和避免,以及wait,waitpid的使用;(4)了解守护进程的创建。2.内容主要上机分析代码文件。systemtest.c6-3.c6-4.c 6-8.c 6-9.c其他略。3.步骤1)Linux进程的创建创建进程可以采用几种方式。可以执行一个程序(这会导致新进程的创建),也可以在程序内调用一个 fork 或 exec来创建新进程。fork 调用会导致创建一个子进程
2、,而 exec 调用则会用新程序代替当前进程上下文。exec系列函数并不创建新进程,调用exec前后的进程ID是相同的。exec系列函数如下。#include <unistd.h>int execv(const char *path,char* const argv);int execve(const char *path, char* const argv,char* const envp);int execvp(const char *file,char* const argv);int execl(const char *path,const char *arg,.);int
3、 execle(const char *path,const char *arg,.);int execlp(const char *file,const char *arg,.);exec函数的主要工作是清除父进程的可执行代码映像,用新程序的代码覆盖调用 exec的进程代码。如果exec执行成功,进程将从新程序的main函数入口开始执行。调用exec后,除进程ID保持不变外,还有下列进程属性也保持不变。(1)进程的父进程ID。(2)实际用户ID和实际用户组ID。(3)进程组ID、会话ID和控制终端。(4)定时器的剩余时间。(5)当前工作目录及根目录。(6)文件创建掩码UMASK。(7)进程的
4、信号掩码。与exec系统调用不同,system将外部可执行程序加载执行完毕后继续返回调用进程。system的返回值就是被加载的程序的返回值。/* systemtest.c for test System. 调用system创建进程*/#include <stdio.h>#include <stdlib.h>void main() /调用system执行“ls -l”,并输出system的返回值 printf("system return code=%dn",system("ls -l"); return 0;【例6.3】 设计一个
5、程序,用fork函数创建一个子进程,在子进程中,要求显示子进程号与父进程号,然后显示当前目录下的文件信息,在父进程中同样显示子进程号与父进程号。/*6-3.c 将一个进程分为两个一样的进程,打印出进程的相关信息 */#include<stdio.h> /*文件预处理,包含标准输入输出库*/#include<stdlib.h> /*文件预处理,包含system、exit等函数库*/#include<unistd.h> /*文件预处理,包含fork、getpid、getppid函数库*/#include<sys/types.h> /*文件预处理,包含
6、fork函数库*/int main () /*C程序的主函数,开始入口*/ pid_t result; result=fork(); /*调用fork函数,返回值存在变量result中*/ int newret; if(result=-1) /*通过result的值来判断fork函数的返回情况,这儿先进行出错处理*/ perror("创建子进程失败"); exit(0); else if (result=0)/*返回值为0代表子进程*/ printf("返回值是:%d,说明这是子进程!n此进程的进程号(PID)是:%dn此进程的父进程号(PPID)是:%dn&qu
7、ot;,result,getpid(),getppid(); execl(“/bin/ls”,”ls”,”-l”,0);/*调用ls程序,显示当前目录下的文件信息*/ else /*返回值大于0代表父进程*/ sleep(10); printf("返回值是:%d,说明这是父进程!n此进程的进程号(PID)是:%dn此进程的父进程号(PPID)是:%dn",result,getpid(),getppid(); 【步骤1】 设计编辑源程序代码。rootlocalhost root#vi 6-3.c【步骤2】用gcc编译程序。rootlocalhost root#gcc 6-3.
8、c o 6-3 【步骤3】运行程序。 编译成功后,执行6-3,此时系统会出现运行结果,根据result的值,先显示Linux系统分配给子进程的进程号(PID)和父进程号(PPID),接着运行ls程序,显示当前目录下的文件信息。再等待10秒钟后,显示父进程的进程号(PID)和父进程号(PPID)。 【步骤4】在6-3.c代码中改变:execl(“/bin/ls”,”ls”,”-l”,0);/*调用ls程序,显示当前目录下的文件信息*/替换为:printf("执行前的进程号(PID)是:%dn",getpid(); /*显示输出进程号*/printf("执行前的父进程
9、号(PPID)是:%dn",getppid();/*显示输出父进程号*/execv(“6-1”, NULL);/*调用6-1程序 */执行后观察进程的PID和PPID是否有改变。2)Linux进程的终止 (1) 正常终止:(a) 在main函数内执行return语句,这等效于调用exit。(b) 调用exit函数。此函数由ANSIC定义,其操作包括调用各终止处理程序,然后关闭所有标准I/O流等。(c) 调用_exit系统调用函数,此函数由exit调用。(2) 异常终止:(a) 调用abort 。(b) 由一个信号终止。exit, _exit, _Exit 都是进程终止函数。abort
10、产生 SIGABRT 信号。非正常退出,即在程序碰到灾难性错误时强制退出。由于是非正常退出,因此不会做其它任何操作。return与exit的区别在进程操作中exit是结束当前进程或程序并把控制权返回给调用该程序或者进程的进程即父进程并告诉父进程该当前进程的运行状态,而return是从当前函数返回,如果是在main函数中,main函数结束时隐式地调用exit函数,自然也就结束了当前进程。return是语言级别的,它表示了调用堆栈的返回;而exit是系统调用级别的,它表示了一个进程的结束。exit函数是退出应用程序,并将应用程序的一个状态返回给OS,这个状态标识了应用程序的一些运行信息。在main
11、函数里面return(0)和exit(0)是一样的,子函数用return返回;而子进程用exit退出,调用exit时要调用一段终止处理程序,然后关闭所有I/O流。/*6-4.c程序:用exit和_exit函数终止进程的区别*/ #include<stdio.h>/*文件预处理,包含标准输入输出库*/#include<stdlib.h>/*文件预处理,包含exit函数库*/#include<unistd.h> /*文件预处理,包含fork、exit函数库*/#include<sys/types.h> /*文件预处理,提供pid_t的定义*/int
12、main () /*C程序的主函数,开始入口*/ pid_t result;result=fork(); /*调用fork函数,返回值存在变量result中*/if(result=-1) /*通过result的值来判断fork函数的返回情况,这儿先进行出错处理*/perror("创建子进程失败");exit(0);else if (result=0) /*返回值为0代表子进程*/printf("测试终止进程的_exit函数!n");printf("目前为子进程,这一行我们用缓存!");_exit(0);else /*返回值大于0代表父
13、进程*/printf("测试终止进程的exit函数!n");printf("目前为父进程,这一行我们用缓存!");exit(0);3)Linux的僵尸进程(wait/waitpid的使用)僵尸进程是指的父进程已经退出,父进程没有处理子进程的退出信息(包括子进程的返回值和其他的一些东西),使得已退出的子进程就成为僵尸进程Defunct ("zombie")。僵尸进程只是在process table里有一个记录,没有占用其他的资源,除非系统的进程个数的限制已经快超过了,zombie进程不会有更多的坏处。通过在父进程里增加一个wait/wa
14、itpid可以解决僵尸进程问题。一般来说,当父进程 fork()一个子进程后,它必须用 wait() 或者 waitpid() 等待子进程退出。正是这个wait() 动作完全清除子进程退出后的信息。【例题】设计一个程序,要求用户可以选择是否创建子进程,子进程模仿思科(Cisco)1912交换机的开机界面,以命令行的方式让用户选择进入,父进程判断子进程是否正常终止。图1 算法流程/*6-8.c 创建进程(cisco菜单)*/#include<stdio.h> /*文件预处理,包含标准输入输出库*/#include<unistd.h> /*文件预处理,包含fork函数库*/
15、#include<sys/types.h> /*文件预处理,包含fork、wait、waitpid函数库*/#include<sys/wait.h> /*文件预处理,包含wait、waitpid函数库*/#include<stdlib.h> /*文件预处理,包含exit函数库*/void display0(); /*子程序声明*/void display1();void display2();int main () /*程序的主函数,开始入口*/ pid_t result; int status,select,num; void (*fun3)(); /*利
16、用函数指针建立三个子程序*/ fun0=display0; fun1=display1; fun2=display2; printf("1.创建子进程n2.不创建子进程n请输入您的选择:"); scanf("%d",&select); if(select=1) /*如果用户输入1,创建进程*/ result=fork(); /*调用fork函数创建进程,返回值存在变量result中*/ if(result=-1) perror("创建进程出错"); exit(1); if (result=0) /*子进程*/ printf(&
17、quot;这是子进程(进程号:%d,父进程号:%d): ",getpid(),getppid(); printf("进入思科(Cisco)1912交换机开机界面。n "); printf("1 user(s) now active on Management Console.n"); printf("tUser Interface Menun"); printf("t0 Menusn"); printf("t1 Command Linen"); printf("t2 IP C
18、onfigurationn"); printf("Enter Selection:"); scanf("%d",&num); /*运用函数指针,运行相应的子程序*/ if(num>=0&&num<=2) (*funnum)(); exit(0); else waitpid(result,&status,0); /*父进程调用waitpid函数,消除僵尸进程*/ printf("这是父进程(进程号:%d,父进程号:%d)n ",getpid(),getppid(); if(WIFEX
19、ITED(status)=0) printf("子进程非正常终止,子进程终止状态:%dn", WIFEXITED(status); else printf("子进程正常终止,子进程终止状态:%dn", WIFEXITED(status); exit(0); /*子程序部分*/void display0() printf("您选择进入了菜单模式n");void display1() printf("您选择进入了命令行模式n");void display2() printf("您选择进入了IP地址配置模式n&
20、quot;);【步骤 1】: 设计编辑源程序代码 rootlocalhost root#vim 6-8.c【步骤 2】:用gcc编译程序rootlocalhost root#gcc 6-8.c o 6-8【步骤 3】:运行程序 rootlocalhost root#./6-81.创建子进程2.不创建子进程请输入您的选择:2这是父进程(进程号:5028,父进程号:4739)子进程非正常终止,子进程终止状态:0再次运行程序rootlocalhost root#./6-8 1.创建子进程2.不创建子进程请输入您的选择:1 这是子进程(进程号:5044,父进程号:5043): 进入思科(Cisco)1
21、912交换机开机界面。 1 user(s) now active on Management Console. User Interface Menu 0 Menus 1 Command Line 2 IP ConfigurationEnter Selection:0 您选择进入了菜单模式这是父进程(进程号:5043,父进程号:4739)子进程正常终止,子进程终止状态:1 【步骤4】:修改程序试着不用waitpid函数,如下所示:/waitpid(result,&status,0); /*父进程调用waitpid函数,消除僵尸进程*/再次运行程序rootlocalhost root#.
22、/6-8 1.创建子进程2.不复创建子程请输入您的选择:1 这是子进程(进程号:5067,父进程号:5064): 进入思科(Cisco)1912交换机开机界面。 1 user(s) now active on Management Console. User Interface Menu 0 Menus 1 Command Line 2 IP ConfigurationEnter Selection:这是父进程(进程号:5064,父进程号:4739)子进程非正常终止,子进程终止状态:02)Linux守护进程守护进程(Daemon)是运行在后台的一种特殊进程。它独立于控制终端并且周期性地执行某种
23、任务或等待处理某些发生的事件。守护进程的特性:(1)守护进程最重要的特性是后台运行。(2)守护进程必须与其运行前的环境隔离开来。这些环境包括未关闭的文件描述符,控制终端,会话和进程组,工作目录以及文件创建掩码等。这些环境通常是守护进程从执行它的父进程(特别是shell)中继承下来的。(3)守护进程的启动方式有其特殊之处。它可以在Linux系统启动时从启动脚本/etc/rc.d中启动,也可以由作业规划进程crond启动,还可以由用户终端(通常是shell)执行。 编写守护进程的要点:(1) 创建子进程,终止父进程(2) 在子进程中创建新会话(3) 当前工作目录换成其他的路径,如“/”或“/tmp
24、”等(4) 把文件创建掩码设置为0(5) 关闭文件描述符【例】设计两段程序,主程序6-9.c和初始化程序init.c。要求主程序每隔10秒钟向/tmp目录中的日志6-9.log报告运行状态。初始化程序中的init_daemon函数负责生成守护进程。分析 把生成守护进程的部分写成独立的函数init_daemon,放在程序init.c中,方便调用,程序init.c中要编写的是前面守护进程的五步。主程序先调用init_daemon函数,使得主程序运行后成为守护进程,接着主程序用while语句无限循环,每隔10秒钟往6-9.log文件中写入一行文字和当前时间。/*6-9.c程序:主程序每隔一分钟向/t
25、mp目录中的日志6-9.log报告运行状态*/#include <stdio.h> /*文件预处理,包含标准输入输出库*/#include <time.h> /*文件预处理,包含时间函数库*/void init_daemon(void); /*守护进程初始化函数*/ int main() /*C程序的主函数,开始入口*/ FILE *fp; time_t t; init_daemon(); /*初始化为daemon*/ while(1) /*无限循环,每隔10秒钟向6-9.log写入运行状态*/ sleep(10); /*睡眠10秒钟*/ if(fp=fopen(&qu
26、ot;6-9.log",”a+”) >=0)/*打开6-9.log文件,若没有此文件,创建它*/ t=time(0); fprintf(fp,"守护进程还在运行,时间是: %s",asctime(localtime(&t) ); fclose(fp); /*初始化程序init.c程序代码如下:init.c程序:生成守护进程*/#include <unistd.h> #include <signal.h> #include <sys/param.h> #include <sys/types.h> #inc
27、lude <sys/stat.h> #include<stdlib.h> void init_daemon(void) pid_t child1,child2; int i; child1=fork(); if(child1>0) /*(1)创建子进程,终止父进程*/ exit(0); /*这是子进程,后台继续执行*/ else if(child1< 0) perror("创建子进程失败"); /*fork失败,退出*/ exit(1); setsid(); /*(2)在子进程中创建新会话*/ chdir("/tmp"); /*(3)改变工作目录到"/tmp"*/ umask(0); /*(4)重设文件创建掩码*/ for(i=0;i< NOFILE;+i) /*(5)关闭文件描述符*/ close(i); return;【步骤 1】:设计编辑源程序代码rootlo
温馨提示
- 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
- 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
- 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
- 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
- 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
- 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
- 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。
最新文档
- 生产流程再造之路
- 色彩魔法课堂
- 硕士之旅:理论探索与实践
- 增材制造与创新设计:从概念到产品 课件 第4、5章 增材制造前处理及工艺规划、增材制造后处理及经验总结
- 农业盛季财务透析
- 垃圾分类你我共建
- 迈向明日启航梦想
- 外汇质押合同(2篇)
- 2024深圳二手房购房定金及房屋维修保养服务合同3篇
- 标准格式离婚协议书
- 办公楼暖通空调系统的节能优化方案
- 秦代建筑配色特征研究报告
- 关于春联来源的研究报告
- 省级非急救医疗转运管理规范
- 煤泥综合利用的可行性研究报告
- 三年级《剪窗花》课件
- 学前儿童发展心理学(高职)全套教学课件
- 2023年手机维修行业分析报告及未来五至十年行业发展报告
- 【SPD】医院器械耗材SPD管理技术方案
- 220kV及以下变电站设备全面巡视标准
- 未成年人保护法ppt
评论
0/150
提交评论