C语言模拟银行家算法

C语言模拟银行家算法银行家算法需求:一个程序对资源的最大需求量不超过系统的最大资源程序可以分多次申请资源,但是申请资源的总量不能超过最大需求量当系统现有资源不能满足程序的需求时,可以推迟分配资源,但是总能满足程序对资源的需求当程序获得了全部的资源后,要在有限的时间内归还资源系统的安全/不安全状态:在程序申请资源时,当系统的拥有的资源不能满足程序剩余所需的全部资源时,则处于不安全状态C代码实现:头文件的导入和预定义#include<stdio.h>#include<stdli

大家好,又见面了,我是你们的朋友全栈君。

银行家算法需求:

  1. 一个程序对资源的最大需求量不超过系统的最大资源
  2. 程序可以分多次申请资源,但是申请资源的总量不能超过最大需求量
  3. 当系统现有资源不能满足程序的需求时,可以推迟分配资源,但是总能满足程序对资源的需求
  4. 当程序获得了全部的资源后,要在有限的时间内归还资源

系统的安全/不安全状态:

在程序申请资源时,当系统的拥有的资源不能满足程序剩余所需的全部资源时,则处于不安全状态

C代码实现:

  1. 头文件的导入和预定义
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
#include <sys/types.h>
#include <unistd.h>
#include <fcntl.h>
#include <sys/mman.h>

#define RESOURCES_MAX 5//系统拥有5种资源
#define u32 unsigned int
#define u8 char
#define TRUE 1
#define FALSE 0
#define programs_t struct programs *
#define critical_resources_t struct critical_resources *
  1. 结构体和枚举的创建
/*创建资源名枚举类型*/
enum Resources
{ 
   
	resource1 , resource2 , resource3 , resource4 , resource5
};

/* 父进程和子进程的共享资源 system_possess_resouces 临界资源 系统剩余的资源数量 wait_visit_number 判断有多少个进程在等待访问临界资源 wait_get_number 判断有多少个进程在等待资源的分配,等待数量等于总进程数时代表出现死锁 all_programs_size 总进程数量 sinal_number 信号量 program_set_up 当前进程的数量 max_programs 存储最大进程数(当n个进程都初始化完毕后才接着往下运行) sleep_time 每个子进程创建出来后都会通过休眠来和其他子进程错开cpu时间避免随机数相同 */
struct critical_resources
{ 
   
		u32 system_possess_resources[RESOURCES_MAX];
		u8  wait_visit_number;
		u8  wait_get_number;
		u8	all_programs_size;
		u8  signal_number; 
		u8  program_set_up;
		u8  max_programs;
		u8  sleep_time;
};

/* 进程需求结构体 max_resources 进程需要的全部资源 get_resources 进程获取的资源数量 need_resources 进程需要的资源数量 random_next_resources 进程这次要申请多少资源,利用随机数来确定 program_number 进程号 judge_success_get_resources 判断是否成功分配到了资源,是则random_next_resources清空 */ 
struct programs 
{ 
   
	u32 max_resources[RESOURCES_MAX];
	u32 get_resources[RESOURCES_MAX];
	u32 need_resources[RESOURCES_MAX];
    u32 random_next_resources[RESOURCES_MAX];
    pid_t  program_number;
    u8  judge_success_get_resources;
};

  1. 进程阻塞函数
/* 循环等待信号量 */
void program_wait(critical_resources_t crts)
{ 
   
	if(crts->signal_number <= 0)
	{ 
    
		crts->wait_visit_number++;//等待进程数量+1
	    while(TRUE)
	    { 
   
	        if(crts->signal_number > 0)//如果信号量可用则跳出
	            break;
	    }
	}	
    crts->signal_number--;//信号量-1
    crts->wait_visit_number--;
}
  1. 释放信号量函数
void release_signal(critical_resources_t crts)
{ 
   
	crts->signal_number++;
}
  1. 申请资源函数
u8 request_resources(critical_resources_t crts , programs_t prg)
{ 

/*如果为TRUE则代表上一次的资源申请已经分配完毕, 可以再进行新的信号量个数申请, 如果为FALSE则代表上一次的资源申请系统并没有满足, 接着进行上一次的申请*/
if(TRUE == prg->judge_success_get_resources)
{ 

for(int i = 0 ; i < RESOURCES_MAX ; i++)
{ 

if(0 == prg->need_resources[i])
{ 

printf("%d need resource%d zero:\n" ,prg->program_number, i + 1);
prg->random_next_resources[i] = 0;
continue;
}
prg->random_next_resources[i] = (random()%prg->need_resources[i] + 1);
printf("%d random request resource%d size:%d \n" ,prg->program_number, i + 1 , prg->random_next_resources[i]);
//usleep(1000);
}
}
/* 对系统安全性进行判断,如果分配资源后系统处于不安全状态则不给予分配 */
if( prg->need_resources[resource1] <= crts->system_possess_resources[resource1]
&& prg->need_resources[resource2] <= crts->system_possess_resources[resource2]
&& prg->need_resources[resource3] <= crts->system_possess_resources[resource3]
&& prg->need_resources[resource4] <= crts->system_possess_resources[resource4]
&& prg->need_resources[resource5] <= crts->system_possess_resources[resource5])
{ 

for(int i = 0 ; i < RESOURCES_MAX ;i++)
{ 

crts->system_possess_resources[i] -= prg->random_next_resources[i];
prg->need_resources[i] -= prg->random_next_resources[i];
prg->get_resources[i] += prg->random_next_resources[i];
}
bzero(prg->random_next_resources,sizeof(prg->random_next_resources));
}
else
{ 

printf("System resources not suffice satisfy %d operation\n" , prg->program_number);
return FALSE;
}
return TRUE;
}
  1. main主函数体
int main(int argc , char ** argv)
{ 

if(argc < 2)
{ 

perror("parameter error");
exit(1);
}
//使用mmap的文件映射来实现父进程和子进程的共享内存,因为进程之间有从属关系,所以在fd处只需要传入-1
critical_resources_t crt = (critical_resources_t)mmap(NULL , sizeof(struct critical_resources) , PROT_READ | PROT_WRITE , MAP_ANON | MAP_SHARED , -1 , 0); 
//共享内存的初始化
for(int i = 0 ; i < RESOURCES_MAX ; i++)
crt->system_possess_resources[i] = 10;	
crt->wait_visit_number = 0;
crt->wait_get_number = 0;
crt->all_programs_size = atoi(argv[1]);
crt->signal_number = 1; 
crt->program_set_up = 0;
crt->sleep_time = 1;
crt->max_programs = 0;
pid_t pid;
//循环创建进程
for(int i = 0 ; i < atoi(argv[1]) ; ++i)
{ 

if(0 == (pid = fork()))
break;
}
if(pid > 0)
{ 

//父进程循环等待子进程的结束
while(TRUE)
{ 

if(atoi(argv[1]) == crt->program_set_up)
{ 

crt->program_set_up = 0;	
}
if(0 == crt->all_programs_size)
break;
wait(NULL);
}
printf("all programs operation end..\n");
}
else
{ 

sleep(crt->sleep_time++);	
//随机数种子
srand((unsigned)time(NULL));
//创建进程资源需求结构体
struct programs prm;
//初始化进程需求结构体
bzero(prm.get_resources , sizeof(prm.get_resources));
bzero(prm.need_resources , sizeof(prm.need_resources));
bzero(prm.random_next_resources , sizeof(prm.random_next_resources));
prm.program_number = getpid();
prm.judge_success_get_resources = TRUE;
printf("program %d set up success\n" , prm.program_number);
//进程数量+1
crt->program_set_up++;
//循环随机生成进程需要的最大资源
for(int i  = 0 ; i < RESOURCES_MAX ; i++) 
{ 

prm.max_resources[i] = (rand()%10 + 1);
prm.need_resources[i] = prm.max_resources[i];
}
//printf("%d max need resources : %d , %d , %d , %d , %d" , prm.program_number , prm.max_resources[resource1] , prm.max_resources[resource2] , prm.max_resources[resource3] , prm.max_resources[resource4]);
printf("%d max need resources : " , prm.program_number);
for(int i = 0 ; i < RESOURCES_MAX ; i++)
{ 

printf("%d " , prm.max_resources[i]);
}
printf("\n");
while(TRUE)//运行到这里开始阻塞等待所有子进程都初始化完毕再接着运行
{ 

if(crt->max_programs == atoi(argv[1]))
break;
}
while(TRUE)
{ 

//阻塞等待信号量
program_wait(crt);
//申请资源
if(TRUE == (prm.judge_success_get_resources = request_resources(crt,&prm)))
bzero(prm.random_next_resources,sizeof(prm.random_next_resources));
else
usleep(1000);
//判断是否用完所有的资源
if(0 == prm.need_resources[resource1] && 
0 == prm.need_resources[resource2] &&
0 == prm.need_resources[resource3] &&
0 == prm.need_resources[resource4] &&
0 == prm.need_resources[resource5])
{ 

printf("\n%d operantion end..." , prm.program_number);
for(int i = 0 ; i < RESOURCES_MAX ; i++)//归还系统的资源
crt->system_possess_resources[i] += prm.max_resources[i];
crt->all_programs_size--;//运行进程数-1
release_signal(crt);//释放信号量
break;//跳出循环
}
release_signal(crt);
}
}
return 0;
}

这是之前的一个操作系统作业,本来还希望实现打印进程资源需求表,但是似乎需要再创建一个共享内存进行链表操作,比较懒就没有实现

在打印过程中是否存在一个进程还未打印结束出现另一个进程抢占打印造成两个进程的输出内容错乱的风险?

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 举报,一经查实,本站将立刻删除。

发布者:全栈程序员-用户IM,转载请注明出处:https://javaforall.cn/163235.html原文链接:https://javaforall.cn

【正版授权,激活自己账号】: Jetbrains全家桶Ide使用,1年售后保障,每天仅需1毛

【官方授权 正版激活】: 官方授权 正版激活 支持Jetbrains家族下所有IDE 使用个人JB账号...

(0)


相关推荐

  • c语言中的offset_c语言中/和%的区别

    c语言中的offset_c语言中/和%的区别今天看libPhenom源代码,看到他们使用的JSON解析库参考的是JanssonJSON解析库。于是就去网上查了这个库,找到了官方网站:http://www.digip.org/jansson/。找了一下发现在Github上能够下载源代码,于是下载了源代码来瞅瞅。    看了一会儿发现有一块代码一直看不明白,就比如说如下的代码:json_t*json_object(void)

  • 提升苹果电脑速度的10个小技巧[通俗易懂]

    提升苹果电脑速度的10个小技巧[通俗易懂]众所周知,随着时间的流逝,包括Mac在内的所有计算机的速度都会降低。除了换电脑,还是有许多简单的调整可以提高计算机的性能并加快运行速度较慢的Mac,而且这些调整不会花费一分钱。1.升级macOS许多人仍然相信操作系统升级的神话总是会降低计算机的速度。尽管有时它们在旧Mac可能会出现性能问题,但这些更新通常弊大于利。它们包括错误修复,修补程序和改进,这些改进通常会提高Mac的速度。这些操作系统更新文件可能很大。因此,如果硬盘驱动器空间不足,则可能需要先释放硬盘空间。2.释放硬盘空间当您的存储驱动器达到其

  • 调试coredump步骤(coredump原理)

    linux系统中某个进程突然崩溃终止,该从哪方面入手分析问题?

  • 网络营销推广案例ppt_网络营销和推广的方法

    网络营销推广案例ppt_网络营销和推广的方法电驴资源下面是用户共享的文件列表,安装电驴后,您可以点击这些文件名进行下载一┳═┻︻▃内容简介处附有网盘快速下载通道▃︻┻═┳一[实战网络营销.网络推广经典案例战术解].扫描版.张书乐.pdf详情68.1MB全选68.1MB下载地址(拷贝到电驴或者迅雷即可下载):ed2k://|file|%5B%E5%AE%9E%E6%88%98%E7%BD%91%E7%BB%9C%E8%9…

    2022年10月19日
  • 关于Web应用开发流程的总结「建议收藏」

    关于Web应用开发流程的总结「建议收藏」关于Web应用开发流程的总结

  • kali如何更换源(怎样换一个kali源)

    KaliLinux的换源和更新1.修改源文件(需要用root权限)[plain]viewplaincopyvim /etc/apt/sources.list  2.这里修改两个我认为还好的源,因为每个地方不同,选择源的时候建议使用一些常用的吧。比如:阿里云源,中科大源之类的官方源更新的速度太慢了,所以我注释掉了,只使用两

发表回复

您的电子邮箱地址不会被公开。

关注全栈程序员社区公众号