用C语言写一个空闲磁盘存储空间的管理。 建立相应的数据结构; 14 磁盘上建立一个文件,文件长度设为 10MB,用该文件来模拟一个磁盘,磁盘 的物理块大小为 512 字节。 建立进程的数据结构; 时间的流逝可用下面几种方法模拟:(a)按键盘,每按一次可认为过一个时 间单位; (b) 响应 WM_TIMER; 将一批进程对磁盘的请求的情况存磁盘文件,以后可以读出并重放; 使用两种方式产生进程对磁盘的请求:(a)自动产生, (b)手工输入; 显示每次磁盘的请求和空间释放后的相关数据结构的状态; 显示每次磁盘的请求和空间释放后状态; 支持的管理方法:空闲表法、空闲链表法、位示图法。
时间: 2024-02-18 17:05:36 浏览: 49
OS磁盘空闲区管理-C语言实现
5星 · 资源好评率100%
下面是一个简单的示例代码,其中实现了空闲链表法和位示图法。由于空闲表法的实现方式与空闲链表法类似,这里不再赘述。
```c
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define DISK_SIZE 10*1024*1024
#define BLOCK_SIZE 512
#define BLOCK_NUM (DISK_SIZE / BLOCK_SIZE)
// 磁盘块结构体
typedef struct block {
int id; // 块号
struct block *next; // 下一块
} Block;
// 空闲链表法
Block *free_block_head = NULL;
// 位示图法
unsigned char bit_map[BLOCK_NUM / 8];
// 进程结构体
typedef struct process {
int block_id; // 所需块号
struct process *next; // 下一个进程
} Process;
// 进程队列
Process *process_queue_head = NULL;
Process *process_queue_tail = NULL;
// 初始化空闲链表
void init_free_block_list() {
free_block_head = malloc(sizeof(Block));
free_block_head->id = 0;
free_block_head->next = NULL;
Block *p = free_block_head;
for (int i = 1; i < BLOCK_NUM; i++) {
p->next = malloc(sizeof(Block));
p->next->id = i;
p->next->next = NULL;
p = p->next;
}
}
// 初始化位示图
void init_bit_map() {
memset(bit_map, 0, sizeof(bit_map));
for (int i = 0; i < BLOCK_NUM / 8; i++) {
bit_map[i] = 0xff;
}
}
// 空闲链表法分配物理块
int alloc_block_free_list() {
if (free_block_head == NULL) {
return -1;
}
int block_id = free_block_head->id;
Block *p = free_block_head;
free_block_head = free_block_head->next;
free(p);
return block_id;
}
// 位示图法分配物理块
int alloc_block_bit_map() {
for (int i = 0; i < BLOCK_NUM / 8; i++) {
if (bit_map[i] != 0x00) {
for (int j = 0; j < 8; j++) {
if (((bit_map[i] >> j) & 0x01) == 1) {
bit_map[i] &= ~(1 << j);
return i * 8 + j;
}
}
}
}
return -1;
}
// 释放物理块
void free_block(int block_id) {
if (block_id < 0 || block_id >= BLOCK_NUM) {
return;
}
// 空闲链表法
Block *p = malloc(sizeof(Block));
p->id = block_id;
p->next = free_block_head;
free_block_head = p;
// 位示图法
bit_map[block_id / 8] |= (1 << (block_id % 8));
}
// 将请求写入磁盘文件中
void write_request_to_file(Process *p) {
FILE *fp = fopen("disk_request.txt", "a");
fprintf(fp, "%d\n", p->block_id);
fclose(fp);
}
// 从磁盘文件中读取请求
Process *read_request_from_file() {
FILE *fp = fopen("disk_request.txt", "r");
Process *head = NULL;
Process *tail = NULL;
int block_id;
while (fscanf(fp, "%d", &block_id) != EOF) {
Process *p = malloc(sizeof(Process));
p->block_id = block_id;
p->next = NULL;
if (tail == NULL) {
head = p;
tail = p;
} else {
tail->next = p;
tail = p;
}
}
fclose(fp);
return head;
}
// 添加请求进程到队列
void add_process_to_queue(Process *p) {
if (process_queue_head == NULL) {
process_queue_head = p;
process_queue_tail = p;
} else {
process_queue_tail->next = p;
process_queue_tail = p;
}
}
// 从队列中取出一个请求进程
Process *pop_process_from_queue() {
if (process_queue_head == NULL) {
return NULL;
}
Process *p = process_queue_head;
process_queue_head = process_queue_head->next;
if (process_queue_head == NULL) {
process_queue_tail = NULL;
}
return p;
}
// 执行一个请求进程
void execute_process(Process *p) {
int block_id = p->block_id;
int result = alloc_block_free_list();
//int result = alloc_block_bit_map(); // 使用位示图法
if (result == -1) {
printf("Can not allocate block %d for process %p\n", block_id, p);
} else {
printf("Allocate block %d for process %p\n", result, p);
}
free(p);
}
// 执行所有请求进程
void execute_all_processes() {
Process *p;
while ((p = pop_process_from_queue()) != NULL) {
execute_process(p);
}
}
int main() {
init_free_block_list();
init_bit_map();
// 模拟进程对磁盘的请求
int n = 5;
for (int i = 0; i < n; i++) {
Process *p = malloc(sizeof(Process));
p->block_id = i;
p->next = NULL;
add_process_to_queue(p);
write_request_to_file(p);
}
// 从磁盘文件中读取请求
Process *head = read_request_from_file();
Process *p = head;
while (p != NULL) {
execute_process(p);
p = p->next;
}
// 执行所有请求进程
execute_all_processes();
return 0;
}
```
需要注意的是,这里的空闲链表和位示图都是在内存中进行管理的,实际操作系统中需要将它们存储到磁盘上,以便在系统重启后能够恢复。此外,还需要考虑并发访问的问题,比如使用锁来保证同一时间只有一个进程对空闲链表或位示图进行修改。
阅读全文