华工操作系统实验3实验报告及实验步骤详解.docx
- 文档编号:11619403
- 上传时间:2023-06-01
- 格式:DOCX
- 页数:10
- 大小:43.96KB
华工操作系统实验3实验报告及实验步骤详解.docx
《华工操作系统实验3实验报告及实验步骤详解.docx》由会员分享,可在线阅读,更多相关《华工操作系统实验3实验报告及实验步骤详解.docx(10页珍藏版)》请在冰点文库上搜索。
华工操作系统实验3实验报告及实验步骤详解
华南理工大学
操作系统课程实验报告
实验概述
【实验目的】
1.掌握进程的概念,深入理解进程的含义。
认识并理解并发环境中进程执
行的实质问题,了解构成并发机制的进程创建过程;
2.了解在进程创建后通过对进程控制的系统调用,可实现对进程的有效控
制。
掌握在进程执行中对进程进行睡眠、同步、撤消等控制方法;
3•分析进程竞争资源的现象,学习解决进程互斥的方法。
【实验内容】
1、创建新的进程;查看运行进程;换出某个进程;杀死运行进程。
2、采用写者优先重写P94的读者-写者问题,并通过一个读写序列,将算
法与读者优先算法进行比较。
3、P98的53题的上机作业。
【实验原理】
1.简述调用fork创建新进程的过程。
fork()用于创建新的进程,所创建进程为当前进程的子进程,可以通过fork()
函数的返回值来控制进程是在父进程中还是在子进程中。
如果运行在父进程中,则返回PID为子进程的进程号,如果在子进程中,则返回的PID为0。
2•简述信号量的作用及使用方法。
作用:
多进程资源共享时,使用信号量,避免产生死锁。
使用方法:
信号量是一个整数;大于或等于0时代表可供并发进程使用的资源实体数;小于0时代表正在等待使用临界区的进程数;用于互斥的信号量初始值应大于0;只能通过P、V原语操作而改变。
【实验环境】
运行电脑系统:
win7
所用软件:
VMware9.0.0.0
模拟系统:
Ubuntu
实验内容
【实验过程】(实验步骤、记录、数据、分析)
1、创建新的进程:
使用fork()函数
查看运行进程&换出某个进程:
使用execl换出进程,并且用PS来替换以达到查看进程的效果
杀死运行进程:
在父进程后使用kill函数
代码:
#include
#include
#includevunistd.h>
#inelude
intmain()
{
pid_tpid;
pid=fork();//创建进程
if(pid==0)
{
printf("Iamthechild,mypidis%d!
\n",getpid());
execl("/bin/ps","ps","r",NULL);//查看进程和替换进程
}
else
{
sleep
(2);
printf("Iamtheparent,mypidis%d,mychildpidis%d!
\n",getpid(),pid);
kill(getpid(),SIGTERM);//杀死进程
printf("Notkill");
运行结果:
limao@ubuntu:
*$./createforkIamthechild,mypidis12182?
PIDTTYSTATTIME
12102pts/1R+6:
00
COMMAND
PSr
121B1,mychildpidis12182!
Iamtheparent,mypidis已终止limao@ubuntu:
~$|
被execl替换成ps,显示出了当前正在运行的进程,最后父进程运行,由于执行
者优先算法进行比较。
代码:
#include"unistd.h"#include"stdio.h"#include"stdlib.h"#include"signal.h"#include
pthread_mutex_trmutex;
//控制对rc的访问
pthread_mutex_twmutex;
//控制对wc的访问
pthread_mutex_treadDB;
//用于写进程对读进程的互斥
pthread_mutex_twriteDB;
//用于读进程对写进程互斥和写进程之间的互
斥
intrc=0;//正在读或者即将读的进程数目
intwc=0;//即将写的进程数目
pthread_tntid;
voidread_data_base()
{
pthread_ttid;
tid=pthread_self();
printf("reading,tidis%d\n",(unsignedint)tid);
sleep
(2);
}
voidwrite_data_base()
{
pthread_ttid;
tid=pthread_self();
printf("writing,tidis%d\n",(unsignedint)tid);sleep
(2);
}
void*reader(void*ptr)
printf("readercomeing,readytoread...'n");pthread_mutex_lock(&wmutex);pthread_mutex_unlock(&wmutex);
pthread_mutex_lock(&rmutex);
rc=rc+1;
if(rc==1)
pthread_mutex_lock(&readDB);pthread_mutex_unlock(&rmutex);read_data_base();
rc=rc-1;
if(rc==0)
pthread_mutex_unlock(&readDB);
pthread_mutex_unlock(&rmutex);return((void*)0);
}
void*writer(void*ptr)
printf("writercomeing,readytowrite...\n");
pthread_mutex_lock(&wmutex);
wc=wc+1;
if(wc==1)
pthread_mutex_lock(&readDB);pthread_mutex_unlock(&wmutex);
pthread_mutex_lock(&writeDB);write_data_base();
pthread_mutex_lock(&wmutex);
wc=wc-1;
if(wc==O)
pthread_mutex_unlock(&readDB);
pthread_mutex_unlock(&writeDB);pthread_mutex_unlock(&wmutex);return((void*)0);
}
intmain(void)
{
pthread_mutex_init(&wmutex,0);pthread_mutex_init(&rmutex,0);pthread_mutex_init(&writeDB,0);
pthread_mutex_init(&readDB,O);
pthread_create(&ntid,NULL,reader,NULL);pthread_create(&ntid,NULL,reader,NULL);pthread_create(&ntid,NULL,writer,NULL);pthread_create(&ntid,NULL,writer,NULL);pthread_create(&ntid,NULL,reader,NULL);pthread_create(&ntid,NULL,reader,NULL);pthread_create(&ntid,NULL,reader,NULL);pthread_create(&ntid,NULL,writer,NULL);pthread_create(&ntid,NULL,writer,NULL);pthread_exit((void*)pthread_self());exit(O);
}
运行结果:
llmao@iibijntu:
'5time./writerFirstreadytoread…-1266488464
readercomeing,readingftidis曲炖工comeingFreadercomeing,ijfi面comeingfreaderc&meingP”丄leFcomeingF讨屯酊comeing,readfiPcomeing,「凹后comeingFwFiring.tidiswriting,tidiswritingttidiswriting,tidisreading,tidisreading.tidisreading,tidisreading.tidis
readytovrite・readytoread.・readytowrite,readytoread..readytovrite・readytovrite,readytoread・・readytoread..*1274881168-1283273872-1241316352-123291764S-1255695760<249763656*1224524944-1216132248
gml2..S12s
5SB7BBBS*-
0mO.0O4s
优先完成写操作,
结果分析:
写者优先就是说当等待队列中既有读者又有写者时,从结果来看,代码是正确的。
对比读者优先和写者优先,可以看出,写者优先会比读者优先慢一些,这是因为写操作是不能同时运行,会降低并行度。
所以读者优先的效率会略高于写者优先。
3、编写一个使用线程并共享一个公共缓冲区的生产者-消费者问题。
但是,不要
使用信号量或任何其他用来保护共享数据结构的同步原语。
直接让每个线程在需要访问时就访问。
使用sleep和wakeup来处理满和空的条件。
观察需要多长时间会出现比较严重的竞争条件。
例如,可以让生产者一会儿打印一个数字,每
分钟打印不要超过一个数字,因为I/O会影响竞争条件。
(课本98页作业题53)代码:
#include
#include
//缓冲区中的槽数目
#defineMAX1000000000
#defineN5
pthread_mutex_tthe_mutex;
pthread_cond_tcondc,condp;
intcount=0;
void*producer(void*ptr)
{
inti;
for(i=1;i<=MAX;i++)
{
if(count==N)
pthread_cond_wait(&condp,&the_mutex);
count=count+1;
sleep
(1);
if(i%60==0)
printf("running...%d\n",count);
if(count==1)
pthread_cond_signal(&condc);
}
return((void*)0);
}
void*consumer(void*ptr)
{
inti;
for(i=1;i<=MAX;i++)
{
if(count==0)
pthread_cond_wait(&condc,&the_mutex);
count=count-1;
sleep
(2);
if(count==N-1)
pthread_cond_signal(&condp);
}
return((void*)0);
}
intmain()
{
pthread_tpro,con;
pthread_mutex_init(&the_mutex,0);pthread_cond」nit(&condc,0);
pthread_cond_init(&condp,0);
pthread_create(&con,NULL,consumer,NULL);
pthread_create(&pro,NULL,producer,NULL);
pthread_exit((void*)pthread_self());
return0;
}
结果(运行了15分钟左右,此时程序并未停止,但却不再打印):
limao^ubuntu:
〜$time./producerconsumerproblem
running…4
runmng*・*4
running.,.4
running.・.4
running..,4
running*.*4
结果分析:
代码会可能会出现竞争条件,其原因是对count的访问未加限制。
有可能出现如下情况:
缓冲区为空,消费者刚刚读取count的值发现它为0.此
时调度程序决定暂停消费者并启动运行生产者。
生产者向缓冲区加入一个数据项,count加1。
现在count的值变成了1。
它推断认为由于count刚才为0,所以消费者此时一定在睡眠,此时生产调用pthread_cond_signal(&condc)来
唤醒消费者。
但是,消费者此时在逻辑上并未睡眠,所以信号丢失。
当消费者下次运行时,它将测试先前读到的conut值,发现它为0,于是睡眠。
生产者迟早会填满整个缓冲区,然后睡眠。
这样一来,两个线程将永远眨眼下去。
指导教师评语及成绩
评语:
成绩:
批阅日期:
指导教师签名:
- 配套讲稿:
如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。
- 特殊限制:
部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。
- 关 键 词:
- 华工 操作系统 实验 报告 步骤 详解