基于Linux的实现进程的信号量互斥申请操作系统课程设计说明书2

  • 格式:doc
  • 大小:483.00 KB
  • 文档页数:9

中北大学
操作系统课程设计
说明书
学院、系:软件学院
专业:软件工程
学生姓名:1121011046 学号:何志坚
设计题目:基于Linux的实现进程的信号量互斥申请
起迄日期: 2013年11月22日- 2013年12月6日指导教师:康珺
2013 年 11月 6 日
1需求分析
基于Linux的进程同步与通信的模拟实现需要完成以下功能:
(1)创建进程:手动创建几个进程,或者随即创建几个进程,都在界面上完成;要求包括进程的名称(不能重复)、执行时间和申请资源的等待时间等。

在同一时刻
可能有多个进行在内存申请某资源,即可以输入多个进程的资源申请。

(2)3类临界资源的管理,包括申请以及分配等。

分别通过信号量实现或者管程实现。

(3)银行家算法,判断是否可以进行资源的分配。

基于以上的功能,可以使用户选择操作,模拟临界资源的管理和银行家算法。

目的:实现临界资源的管理及死锁的避免。

2 总体设计
进程同步与模拟实现系统分为4个模块:输入输出,进程对资源的随机申请及分配,临界资源管理,银行家算法避免死锁。

输入输出:包括系统运行所需要的进程的名称,执行时间,申请资源的等待时间,进程对资源的需要量等信息以及系统所要显示出的进程的创建信息,资源的分配信息,进行执行信息,进行动态申请资源信息等。

进程对资源的随机申请及分配:根据所输入的进程、资源、以及进程对资源的最大申请情况,随机产生进程当前对资源的申请,输出相应的分配信息与进程执行信息并调用银行家算法对进程的资源申请进行判断。

临界资源的管理:创建相应个数的进程,完成进程的并发执行,使用互斥信号量使各进程互斥的进入各自的临界区对资源进行申请,进程执行完毕后,互斥的对资源进行恢复。

银行家算法避免死锁:对当前进程对资源的申请利用银行家算法进行判断,看系统分配后是否处于安全状态,若处于安全状态,则将资源分配给进程,并输出分配信息,否则对不予以分配。

3.详细设计
在该系统中我主要实现了临界资源管理的模块,该模块中主要使用了结构体数组的数据结构.
3.1进程模拟thread模块
图3.1进程流程图
源代码: void *thread1() { int i,j; int tr=0;
loop:for(i=0;i<a;i++) {
printf("i=%d\n",i);
申请的资源数目大与现有数目 现有资源
数目更新
当前进程睡眠
当前进程执行
释放资源,更新资源数目
if(Max[tr][i]>ZY[i].n)
{
printf("进程%c所申请的%c资源数目大于现有的%c资源数目!,不能进行分配\n",JC[tr].name,ZY[i].type,ZY[i].type);
printf("睡眠%d\n",JC[tr].waittime);
sleep(JC[tr].waittime+2);
//线程睡眠一段时间,让线程释放互斥锁,等待另一个线程使用此锁。

goto loop;
break;
}
}
pthread_mutex_lock(&mut);//声明开始用互斥锁上锁
//a表示资源种类数
//结构体二维数组ZY存放资源数目
//二维数组Max存放进程申请资源的数目
for(i=0;i<a;i++)
{
ZY[i].n-=Max[tr][i];
}
printf("进程%c",JC[tr].name);
for(i=0;i<a;i++)
{
printf("申请%c资源%d个",ZY[i].type,Max[tr][i]);
}
printf("成功\n");
printf("系统剩余资源个数:");
for(i=0;i<a;i++)
{
printf("%c(%d个) ",ZY[i].type,ZY[i].n);
}
printf("\n");
pthread_mutex_unlock(&mut);//互斥锁到此结束 //2.执行当前进程
printf("进程%c 正在执行.....\n",JC[tr].name); sleep(JC[tr].runtime);
printf("进程%c 执行完成\n",JC[tr].name); //3.利用互斥信号量对资源数目进行恢复 pthread_mutex_lock(&mut); for(i=0;i<a;i++) {
ZY[i].n+=Max[tr][i];
}
pthread_mutex_unlock(&mut); }
3.2进程创建模块
图3.2进程创建流程图
源代码:
为进程分配内存
创建成功
创建失败
创建进程
void thread_create()//创建线程
{
int temp,i;
memset(&thread, 0, sizeof(thread));//为线程分配内存空间
/*创建线程*/
if((temp = pthread_create(&thread[0], NULL, thread1,NULL)) != 0)
//第一个参数为指向线程标识符的指针,第二个参数用来设置线程属性,第三个参数是线程运行函数的起始地址,最后一个参数是运行函数的参数。

//当创建线程成功时,函数返回0,若不为0则说明创建线程失败
printf("进程%c创建失败!\n",JC[0].name);
else
printf("进程%c被创建\n",JC[0].name);
if((temp = pthread_create(&thread[1], NULL, thread2,NULL)) != 0)
//第一个参数为指向线程标识符的指针,第二个参数用来设置线程属性,第三个参数是线程运行函数的起始地址,最后一个参数是运行函数的参数。

//当创建线程成功时,函数返回0,若不为0则说明创建线程失败
printf("进程%c创建失败!\n",JC[1].name);
else
printf("进程%c被创建\n",JC[1].name);
if((temp = pthread_create(&thread[2], NULL, thread3,NULL)) != 0)
//第一个参数为指向线程标识符的指针,第二个参数用来设置线程属性,第三个参数是线程运行函数的起始地址,最后一个参数是运行函数的参数。

//当创建线程成功时,函数返回0,若不为0则说明创建线程失败
printf("进程%c创建失败!\n",JC[2].name);
else
printf("进程%c被创建\n",JC[2].name);
if((temp = pthread_create(&thread[3], NULL, thread4,NULL)) != 0)
//第一个参数为指向线程标识符的指针,第二个参数用来设置线程属性,第三个参数是线程运行函数的起始地址,最后一个参数是运行函数的参数。

//当创建线程成功时,函数返回0,若不为0则说明创建线程失败
printf("进程%c创建失败!\n",JC[3].name);
else
printf("进程%c被创建\n",JC[3].name);
if((temp = pthread_create(&thread[4], NULL, thread5,NULL)) != 0)
//第一个参数为指向线程标识符的指针,第二个参数用来设置线程属性,第三个参数是线程运行函数的起始地址,最后一个参数是运行函数的参数。

//当创建线程成功时,函数返回0,若不为0则说明创建线程失败
printf("进程%c创建失败!\n",JC[4].name);
else
printf("进程%c被创建\n",JC[4].name);
}
运行结果:
图3.3进程输入信息
图3.4进程执行信息
图3.5 进程执行信息
4.心得体会
经过这次的操作系统课程设计,让我经历了一次有意义的项目开发过程,让我了解了团队合作的重要性,起初我们只是在不停的各干各的,发现根本不可能完成预期的任务,后来我们坐下来讨论了系统的功能,然后各司其职,发现效果真的不一样,虽然在这两周的时间里我们做了很多,中间也遇到了一些问题,比如说临界资源管理模块和银行家模块怎样结合起来,起初是将两个交叉起来,可是效果不是很好,最后还是决定将它们分开,慢慢地其他问题也同样得到了解决,这就是团队合作的力量,这个系统需要完善的内容还有很多,我们以后还会在一起讨论完善并改进,在此过程中,我也发现了编程是需要绝对的耐心与细心的,不然会造成一些难以修改的错误,导致整个项目进展出现问题。

这对我们真的是一次很好的锻炼。