操作系统第二次实验.docx
- 文档编号:27643553
- 上传时间:2023-07-03
- 格式:DOCX
- 页数:14
- 大小:438.43KB
操作系统第二次实验.docx
《操作系统第二次实验.docx》由会员分享,可在线阅读,更多相关《操作系统第二次实验.docx(14页珍藏版)》请在冰豆网上搜索。
操作系统第二次实验
实验一****题目
实验日期:
2012-11-2
(1)实验任务:
掌握进程的概念
(2)掌握系统调用
(3)设计程序,实现结果的不可再现性;使用同步原语,实现结果的可再现性
(4)设计程序,对系统的进程数目进行压力测试,对运行时间进行监控
实验原理:
1.进程是操作系统结构的基础;是一个正在执行的程序;计算机中正在运行的程序实例;可以分配给处理器并由处理器执行的一个实体;由单一顺序的执行显示,一个当前状态和一组相关的系统资源所描述的活动单元。
进程是一个具有独立功能的程序关于某个数据集合的一次运行活动。
它可以申请和拥有系统资源,是一个动态的概念,是一个活动的实体。
它不只是程序的代码,还包括当前的活动,通过程序计数器的值和处理寄存器的内容来表示。
2.程序在并发执行时,由于失去了封闭性,也将导致其再失去可再现性。
程序顺序执行,只要程序执行时的环境和初始条件相同,当程序重复执行时,不论它是从头到尾不停顿地执行,还是“停停走走”地执行,都将获得相同的结果。
3.压力测试是测试系统在非正常的、超负荷的条件下的运行情况,用来评估在超越最大负载的情况下系统将如何运行,考验系统在正常的情况下对某种负载强度的承受能力。
压力测试就是一种破坏性的测试。
压力测试是在一种需要反常数量、频率或资源的方式下运行系统,用以判断系统的稳定性和可靠性。
4.简单的系统调用
(1)fork();当fork()函数返回值为0时,子进程成功创建,以下为子进程作用域
(2)syscall(SYS_getpid);调用系统函数syscall(),返回当前进程号
(3)getpid();调用系统函数getpid(),返回当前进程号
(4)execl();
头文件:
#include
原型:
intexecl(constchar*path,constchar*arg,...);
函数说明:
execl()用来执行参数path字符串所代表的文件路径,接下来的参数代表执行该文件时传递的argv[0],argv[1].....是后一个参数必须用空指针NULL作结束
返回值:
成功则不返回值,失败返回-1,失败原因存于errno中
实验源程序:
1.创建进程:
#include
#include
#include
intmain(intargc,char**argv)
{
intpid=fork();
if(pid<0)
{
printf("error!
");
}
elseif(pid==0)
{
printf("Thisisthechildprocess!
");
}
else{
printf("Thisistheparentprocess!
childprocessid=%d",pid);
}
return0;
}
2.程序的不可再现性:
#include
intmain(intargc,char*argv[])
{
printf("Thead%shasstart!
\n",argv[1]);
sleep(3);
printf("Thread%sended\n",argv[1]);
return(0);
}
$catecp1.c
#include
#include
#include
#include
voidmain()
{
int*status;
char*f="./tc_print";/*要执行的程序名*/
char*argv1[3],*argv2[3],*argv3[3],*argv4[3];/*执行程序所需的参数*/
argv1[0]="./tc_print";
argv1[1]="1";
argv1[2]=0;/*参数结束的标志*/
argv2[0]="./tc_print";
argv2[1]="2";
argv2[2]=0;
argv3[0]="./tc_print";
argv3[1]="3";
argv3[2]=0;
argv4[0]="./tc_print";
argv4[1]="4";
argv4[2]=0;
if(fork()==0)/*创建进程*/
{
execvp(f,argv1);/*执行程序*/
sleep
(1);
execvp(f,argv2);
sleep
(1);
}
else
{
if(fork()==0)/*创建进程*/
{
execvp(f,argv3);
sleep
(1);
}
else
{wait(status);
execvp(f,argv3);
sleep
(1);
}
}
printf("Endprogram!
\n");
}
3.实现程序结果的可再现性:
#include
intn=0;
intstatus;//改动地点
voidpp()
{
n++;
if(n>=10)return;
wait(&status);//改动地点wait系统调用会使父进程阻塞直到一个子进程结束
if(fork()==0)
{
printf("%d",n);
for(n=0;n<1000000;n++)
;
}
elsepp();
}
intmain()
{
inti;
for(i=0;i<3;i++)
{pp();
printf("\n");
}
return0;
}
3.用信号量semget()、semctl()、semop()实现进程同步:
#include
#include
#include
#include
#include
#include
#include
#include
#defineSEMKEY(key_t)0x200
typedefunion_senum{
intval;
structsemid_ds*buf;
ushort*array;
}semun;
staticintsemid;
structsembufp1={0,-1,0};//第一个是索引量,第二个-1是p操作,1是v操作。
structsembufv1={0,1,0};
intinitsem()/*信号量初始化*/
{
semunx;
x.val=0;//用于付信号量初值
if((semid=semget(SEMKEY,1,0600|IPC_CREAT|IPC_EXCL))==-1)//创建信号量集,1为信号量集的中信号的个数
//1为信号量集中信号量个数
{
if(errno==EEXIST)//已经存在,则获得ID号.
semid=semget(SEMKEY,1,0);
}
if(semctl(semid,0,SETVAL,x)==-1)0索引号,设置初值,x为初值
{
perror("semctlfailed\n");
return(-1);
}
return(semid);
}
main()/*主操作*/
{
inti=0,semid;
intj;
semid=initsem();
if(fork()==0)
{
semop(semid,&p1,1);/*p操作*/
for(j=0;j<1000;j++)
{
printf("reader1%d\n",2*j+1);
sleep
(1);
}
printf("reader1finish!
!
!
\n");
}
else
{
if(fork()==0)
{
for(i=0;i<1000;i++)
{
printf("reader2%d\n",2*i);
sleep
(1);
}
printf("reader2finish!
!
!
\n");
semop(semid,&v1,1);
}
}
}
4.创建进可能多的进程,得到这个数目的极限,进程启动后可以进入死循环:
#include
#include
#include
#include
#defineMAXPRO50//此处定义估计最大的进程数,可以设为很大
#defineSELLP10000
intmain(void)
{
longmax=0;
pid_tpid,pids[MAXPRO+1];
longi,l=0;
for(max=1;max { pid=fork();//不断创建进程 if(pid<0)break; elseif(pid>0) { printf("\nForkprocess%d%d: ",pid,max); pids[max]=pid; } else { while (1) { l++;//进入死循环 } } } for(i=1;i { if(kill(pids[i],SIGKILL)<0)//程序结束时将所有创建的进程强制关闭 { printf("\nProcess%dcannotkill! ",pids[i]); } elseprintf("\nProcess%dhavebeenkill! ",pids[i]); } printf("\nThemaxprocessesnumberis: %d\n",max);//输出最大值 return1; } 5.递归创建200个进程,记录总体创建的起始时间和结束时间,最后求创建单个线程的平均时间: #include #include #include #include #include #include #defineMAXPRO200//创建200个进程 #defineSELLP10000 #defineTESTTIME10 longmax=0,l=0; voidmyfork()//递归函数 { pid_tpid; intstatus; //if(max>=MAXPRO)exit (1); max++; pid=fork();//递归创建进程 if(pid<0)exit (1); if(pid>0) { waitpid(pid,&status,0);//等待子进程结束 if(max<2)return; exit (1); } if(pid==0) { if(max>=MAXPRO)exit (1); myfork(); exit (1); } } intmain(void) { longave=0; time_ttime1; structtm*t1,*t2; pid_tpid,pids[MAXPRO+1]; longi,ti; intstatus; structtimevaltv1[TESTTIME],tv2[TESTTIME]; structtimezonetz; for(l=0;l { max=0; gettimeofday(&tv1[l],&tz);//记录开始时间 myfork(); gettimeofday(&tv2[l],&tz);//记录结束时间 } for(l=0;l { printf("\nRound%d: Thestartimeis%ds%dus\n",l+1,tv1[l].tv_sec,tv1[l].tv_usec); printf("Round%d: Theendtimeis%ds%dus\n",l+1,tv2[l].tv_sec,tv2[l].tv_usec); ti=(tv2[l].tv_sec-tv1[l].tv_sec)*1000000+(tv2[l].tv_usec-tv1[l].tv_usec); printf("Round%d: Alltimeis%dus\n",l+1,ti); ave+=ti/MAXPRO; printf("Round%d: Theaveragetimeis%dus\n",l+1,ti/MAXPRO); } printf("Lasttheaveragetimeis%dus\n",ave/TESTTIME); return1; } 实验结果:
- 配套讲稿:
如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。
- 特殊限制:
部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。
- 关 键 词:
- 操作系统 第二次 实验