unix文件系统模拟-操作系统课程设计

本文介绍了一个简单的UNIX文件系统模拟项目,主要包括超级块、位图、inode等关键组件的设计与实现。作者通过C语言实现了文件和目录的基本操作,如创建、删除、读写等。

本周进行操作系统课程设计,在很多的题目中选了个unix文件系统模拟,主要就是操作结构与文件。

为了方便,文件系统结构如下:

Super block -- Block bitmap -- Inode bitmap -- Inode table -- Block zone

其中:

Super block: 存储基本信息

Block bitmap:块分配情况

Inode bitmap:索引节点分配情况

Inode table: Indoe 节点存放区

Block zone:存放数据区

效果如下:


总的说来,做的还是挺简单的,只是实现了基本的功能.而块的分配没有怎么完成,linux系统中一般是通过多级索引的方式为inode分配块.

刚开始我的想法是:inode的块(512B)只写510B,留下2B用于记录下一块的块号,我觉得应该可行,但觉得繁,就没有写下去.所以就没有多余的

块分配操作.知识INode对应一个Block....,太懒了.还有一个缺点,文件指针移动太频繁了,而且都是绝对定位移动(好算,呵呵)

代码如下:

/*核心思想:一切皆是文件
如果是目录:Block中存储的是目录下文件和目录的fcb
如果是文件:Block中存储的是文件的内容
*/
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <malloc.h>
#include <signal.h>

#define BLOCKSIZE 512
#define BLOCKNUM  512
#define INODENUM  30
#define FILENAME "file.dat"

typedef struct{
	unsigned short blockSize;
	unsigned short blockNum;
	unsigned short inodeNum;
	unsigned short blockFree;
	unsigned short inodeFree;
}SuperBlock;

typedef struct{
	unsigned short inum;
	char fileName[10];
	unsigned short isDir;  // 0-file 1-dir
	unsigned short iparent;
	unsigned short length;    //if file->filesize  if dir->filenum
	unsigned short blockNum;
}Inode,*PtrInode;

//Fcb用于存储文件与 目录信息,主要用途:将一个目录下的所有文件(包括目录)写入到该目录对应的Block中
typedef struct {
    unsigned short inum;
    char fileName[10];
    unsigned short isDir;
}Fcb,*PtrFcb;


typedef struct{
	char userName[10];
	char passWord[10];
}User;


char blockBitmap[BLOCKNUM];
char inodeBitmap[INODENUM];

SuperBlock superBlock;
User curUser=(User){"root","root"};

unsigned short currentDir; //current inodenum
FILE *fp;
const unsigned short superBlockSize=sizeof(superBlock);
const unsigned short blockBitmapSize=sizeof(blockBitmap);
const unsigned short inodeBitmapSize=sizeof(inodeBitmap);
const unsigned short inodeSize=sizeof(Inode);
const unsigned short fcbSize=sizeof(Fcb);
char		*argv[5];
int argc;


void createFileSystem()
/*创建*/
{
	long len;
	PtrInode fileInode;
	if ((fp=fopen(FILENAME,"wb+"))==NULL)
	{
		printf("open file %s error...\n",FILENAME);
		exit(1);
	}

    //init bitmap
	for(len=0;len<BLOCKNUM;len++)
        blockBitmap[len]=0;

    for(len=0;len<INODENUM;len++)
        inodeBitmap[len]=0;

     //memset

	for (len=0;len<(superBlockSize+blockBitmapSize+inodeBitmapSize+inodeSize*INODENUM+BLOCKSIZE*BLOCKNUM);len++)
	{
		fputc(0,fp);
	}
	rewind(fp);

	//init superBlock
	superBlock.blockNum=BLOCKNUM;
	superBlock.blockSize=BLOCKSIZE;
	superBlock.inodeNum=INODENUM;
	superBlock.blockFree=BLOCKNUM-1;
	superBlock.inodeFree=INODENUM-1;

	fwrite(&superBlock,superBlockSize,1,fp);

	//create root
	fileInode=(PtrInode)malloc(inodeSize);
	fileInode->inum=0;
	strcpy(fileInode->fileName,"/");
	fileInode->isDir=1;
	fileInode->iparent=0;
	fileInode->length=0;
	fileInode->blockNum=0;

	//write / info to file
	inodeBitmap[0]=1;
	blockBitmap[0]=1;
	fseek(fp,superBlockSize,SEEK_SET);
	fwrite(blockBitmap,blockBitmapSize,1,fp);
	fseek(fp,superBlockSize+blockBitmapSize,SEEK_SET);
	fwrite(inodeBitmap,inodeBitmapSize,1,fp);
	fseek(fp,superBlockSize+blockBitmapSize+inodeBitmapSize,SEEK_SET);
	fwrite(fileInode,inodeSize,1,fp);
	fflush(fp);

	//point to currentDir
	currentDir=0;

}

void openFileSystem()
/*如果FILENAME可读,则代表之前已有信息,并读取相应数据    如果不可读,则创建文件系统 */
{

	if((fp=fopen(FILENAME,"rb"))==NULL)
	{
		createFileSystem();
	}
	else
	{
	    if ((fp=fopen(FILENAME,"rb+"))==NULL)
        {
            printf("open file %s error...\n",FILENAME);
            exit(1);
        }
	    rewind(fp);
        //read superBlock from file
        fread(&superBlock,superBlockSize,1,fp);

        //read bitmap from file
        fread(blockBitmap,blockBitmapSize,1,fp);
        fread(inodeBitmap,inodeBitmapSize,1,fp);

        //init current dir
        currentDir=0;

	}

}


void createFile(char *name,int flag) //flag=0 ->create file   =1 ->directory
{
	int i,nowBlockNum,nowInodeNUm;
	PtrInode fileInode=(PtrInode)malloc(inodeSize);
	PtrInode parentInode=(PtrInode)malloc(inodeSize);
	PtrFcb fcb=(PtrFcb)malloc(fcbSize);

	//the available blockNumber
	for(i=0;i<BLOCKNUM;i++)
	{
		if(blockBitmap[i]==0)
		{
			nowBlockNum=i;
			break;
		}

	}

	//the available inodeNumber
	for(i=0;i<INODENUM;i++)
		{
			if(inodeBitmap[i]==0)
			{
				nowInodeNUm=i;
				break;
			}

		}

	//init fileINode struct
	fileInode->blockNum=nowBlockNum;
	strcpy(fileInode->fileName,name);
	fileInode->inum=nowInodeNUm;
	fileInode->iparent=currentDir;
	if(flag==0)
	{
		fileInode->isDir=0;
	}
	else
	{
		fileInode->isDir=1;
	}
	fileInode->length=0;

	//write fileInfo to file
	fseek(fp,superBlockSize+blockBitmapSize+inodeBitmapSize+inodeSize*nowInodeNUm,SEEK_SET);
	fwrite(fileInode,inodeSize,1,fp);

	//update superBlock and bitmap
	superBlock.blockFree-=1;
	superBlock.inodeFree-=1;
	blockBitmap[nowBlockNum]=1;
	inodeBitmap[nowInodeNUm]=1;

	//init fcb info
	strcpy(fcb->fileName,fileInode->fileName);
	fcb->inum=fileInode->inum;
	fcb->isDir=fileInode->isDir;

	//update to file ...

	//update parent dir block info
	fseek(fp,superBlockSize+blockBitmapSize+inodeBitmapSize+currentDir*inodeSize,SEEK_SET);
	fread(parentInode,inodeSize,1,fp);
	fseek(fp,superBlockSize+blockBitmapSize+inodeBitmapSize+INODENUM*inodeSize+parentInode->blockNum*BLOCKSIZE+parentInode->length*fcbSize,SEEK_SET);
	fwrite(fcb,fcbSize,1,fp);

	//update parent dir inode info
	parentInode->length+=1;
	fseek(fp,superBlockSize+blockBitmapSize+inodeBitmapSize+currentDir*inodeSize,SEEK_SET);
	fwrite(parentInode,inodeSize,1,fp);

	// free resource
	free(fileInode);
	free(parentInode);
	free(fcb);
}



void list()
{
	int i;
	PtrFcb fcb=(PtrFcb)malloc(fcbSize);
	PtrInode parentInode=(PtrInode)malloc(inodeSize);

	//read parent inode info from file
	fseek(fp,superBlockSize+blockBitmapSize+inodeBitmapSize+currentDir*inodeSize,SEEK_SET);
	fread(parentInode,inodeSize,1,fp);

	//point to parent dir block
	fseek(fp,superBlockSize+blockBitmapSize+inodeBitmapSize+inodeSize*INODENUM+parentInode->blockNum*BLOCKSIZE,SEEK_SET);

	//list info
	for(i=0;i<parentInode->length;i++)
	{
		fread(fcb,fcbSize,1,fp);
		printf("Filename: %-10s",fcb->fileName);
		printf("Inode number: %-2d    ",fcb->inum);
		if(fcb->isDir==1)
		{
		printf("Directory\n");
		}
		else
		{
			printf("Regular file\n");
		}
	}

	//free resource
	free(fcb);
	free(parentInode);
}


int findInodeNum(char *name,int flag)  //flag=0 ->find file flag=1 -> find dir
{
	int i,fileInodeNum;
	PtrInode parentInode=(PtrInode)malloc(inodeSize);
	PtrFcb fcb=(PtrFcb)malloc(fcbSize);

	//read current inode info from file
	fseek(fp,superBlockSize+blockBitmapSize+inodeBitmapSize+currentDir*inodeSize,SEEK_SET);
	fread(parentInode,inodeSize,1,fp);

	//read the fcb in the current dir block
	fseek(fp,superBlockSize+blockBitmapSize+inodeBitmapSize+inodeSize*INODENUM+parentInode->blockNum*BLOCKSIZE,SEEK_SET);

	for(i=0;i<parentInode->length;i++)
	{
		fread(fcb,fcbSize,1,fp);
		if(flag==0)
		{
			if((fcb->isDir==0)&&(strcmp(name,fcb->fileName)==0))
					{
						fileInodeNum=fcb->inum;
						break;
					}

		}
		else
		{
			if((fcb->isDir==1)&&(strcmp(name,fcb->fileName)==0))
					{
						fileInodeNum=fcb->inum;
						break;
					}

		}
	}

	if(i==parentInode->length)
			fileInodeNum=-1;

	free(fcb);
	free(parentInode);
	return fileInodeNum;
}

void cd(char *name)
{
	int fileInodeNum;
	PtrInode fileInode=(PtrInode)malloc(inodeSize);
	if(strcmp(name,"..")!=0)
	{
		fileInodeNum=findInodeNum(name,1);
		if(fileInodeNum==-1)
			printf("This is no %s directory...\n",name);
		else
		{
			currentDir=fileInodeNum;
		}
	}
	else
	{
		fseek(fp,superBlockSize+blockBitmapSize+inodeBitmapSize+currentDir*inodeSize,SEEK_SET);
		fread(fileInode,inodeSize,1,fp);
		currentDir=fileInode->iparent;

	}
	free(fileInode);
}

void cdParent()
{
	PtrInode fileInode=(PtrInode)malloc(inodeSize);
	fseek(fp,superBlockSize+blockBitmapSize+inodeBitmapSize+currentDir*inodeSize,SEEK_SET);
	fread(fileInode,inodeSize,1,fp);
	currentDir=fileInode->iparent;

	free(fileInode);
}

void write(char *name)
{
	int fileInodeNum,i=0;
	char c;
	PtrInode fileInode=(PtrInode)malloc(inodeSize);
	if((fileInodeNum=findInodeNum(name,1))!=-1)
	{
		printf("This is a directory,not a file...\n");
		return;
	}

	fileInodeNum=findInodeNum(name,0);
	if(fileInodeNum==-1)
		printf("This is no %s file...\n",name);
	else
	{
		//get inode->blocknum
		fseek(fp,superBlockSize+blockBitmapSize+inodeBitmapSize+fileInodeNum*inodeSize,SEEK_SET);
		fread(fileInode,inodeSize,1,fp);
		//point to the block site
		fseek(fp,superBlockSize+blockBitmapSize+inodeBitmapSize+INODENUM*inodeSize+fileInode->blockNum*BLOCKSIZE,SEEK_SET);
		printf("please input file content(stop by #):\n");
		while((c=getchar())!='#')
		{
			fputc(c,fp);
			i++;
		}

		//update inode->length
		fseek(fp,superBlockSize+blockBitmapSize+inodeBitmapSize+fileInodeNum*inodeSize,SEEK_SET);
		fread(fileInode,inodeSize,1,fp);
		fileInode->length=i-1;
		fseek(fp,-inodeSize,SEEK_CUR);
		fwrite(fileInode,inodeSize,1,fp);
	}

	free(fileInode);

}

void read(char *name)
{
	int fileInodeNum;
	char c;
	PtrInode fileInode=(PtrInode)malloc(inodeSize);
	if((fileInodeNum=findInodeNum(name,1))!=-1)
	{
			printf("This is a directory,not a file...\n");
			return;
	}
	fileInodeNum=findInodeNum(name,0);
	if(fileInodeNum==-1)
		printf("This is no %s file...\n",name);
	else
	{
		//get inode->blocknum
		fseek(fp,superBlockSize+blockBitmapSize+inodeBitmapSize+fileInodeNum*inodeSize,SEEK_SET);
		fread(fileInode,inodeSize,1,fp);
		//point to the block site
		fseek(fp,superBlockSize+blockBitmapSize+inodeBitmapSize+INODENUM*inodeSize+fileInode->blockNum*BLOCKSIZE,SEEK_SET);

		//read content
		if(fileInode->length!=0)
		{
			while((c=fgetc(fp))!=EOF)
			{
				putchar(c);
			}
			printf("\n");
		}

	}

	free(fileInode);
}


void delete(char *name) 
/*delete 一个文件,需要修改SuperBlock,Blockbitmap,Inodebitmap,并更新父节点长度,删除父节点Block中存储的该文件fcb*/ 
{
	int fileInodeNum,i;
	PtrInode fileInode=(PtrInode)malloc(inodeSize);
	PtrInode parentInode=(PtrInode)malloc(inodeSize);
	Fcb fcb[20];
	if(((fileInodeNum=findInodeNum(name,0))==-1)&&((fileInodeNum=findInodeNum(name,1))==-1))
	{
		printf("This is no %s...\n",name);
	}
	else
	{
		if((fileInodeNum=findInodeNum(name,0))==-1)
		{
			fileInodeNum=findInodeNum(name,1);
		}

		fseek(fp,superBlockSize+blockBitmapSize+inodeBitmapSize+fileInodeNum*inodeSize,SEEK_SET);
		fread(fileInode,inodeSize,1,fp);

		fseek(fp,superBlockSize+blockBitmapSize+inodeBitmapSize+fileInode->iparent*inodeSize,SEEK_SET);
		fread(parentInode,inodeSize,1,fp);


		//update parent info
		fseek(fp,superBlockSize+blockBitmapSize+inodeBitmapSize+INODENUM*inodeSize+parentInode->blockNum*BLOCKSIZE,SEEK_SET);
		for(i=0;i<parentInode->length;i++)
		{
			fread(&fcb[i],fcbSize,1,fp);
				//fcb[i]=tmp;
		}

		fseek(fp,superBlockSize+blockBitmapSize+inodeBitmapSize+INODENUM*inodeSize+parentInode->blockNum*BLOCKSIZE,SEEK_SET);
		for(i=0;i<BLOCKSIZE;i++)
				fputc(0,fp);

		fseek(fp,superBlockSize+blockBitmapSize+inodeBitmapSize+INODENUM*inodeSize+parentInode->blockNum*BLOCKSIZE,SEEK_SET);
		for(i=0;i<parentInode->length;i++)
		{
			if((strcmp(fcb[i].fileName,name))!=0)
			{
					fwrite(&fcb[i],fcbSize,1,fp);
			}
		}

		parentInode->length-=1;
		fseek(fp,superBlockSize+blockBitmapSize+inodeBitmapSize+fileInode->iparent*inodeSize,SEEK_SET);
		fwrite(parentInode,inodeSize,1,fp);
		//update bitmap
		inodeBitmap[fileInodeNum]=0;
		blockBitmap[fileInode->blockNum]=0;

		//update superblock
		superBlock.blockFree+=1;
		superBlock.inodeFree+=1;
	}

	free(fileInode);
	free(parentInode);

}

void updateResource()
{
	rewind(fp);
	fwrite(&superBlock,superBlockSize,1,fp);
	fwrite(blockBitmap,blockBitmapSize,1,fp);
	fwrite(inodeBitmap,inodeBitmapSize,1,fp);
	fclose(fp);
}

void pathSet()
{
	PtrInode curInode=(PtrInode)malloc(inodeSize);
	fseek(fp,superBlockSize+blockBitmapSize+inodeBitmapSize+currentDir*inodeSize,SEEK_SET);
	fread(curInode,inodeSize,1,fp);
	printf("%s@localhost:%s#",curUser.userName,curInode->fileName);
	free(curInode);
}

void systemInfo()
{
	printf("Sum of block number:%d\n",superBlock.blockNum);
	printf("Each block size:%d\n",superBlock.blockSize);
	printf("Free of block number:%d\n",superBlock.blockFree);
	printf("Sum of inode number:%d\n",superBlock.inodeNum);
	printf("Free of inode number:%d\n",superBlock.inodeFree);
}

void help()
{
	printf("command: \n\
	help   ---  show help menu \n\
	sysinfo  --- show system base information \n\
	cls  ---  clear the screen \n\
	cd     ---  change directory \n\
	mkdir  ---  make directory   \n\
	touch  ---  create a new file \n\
	cat   ---  read a file \n\
	write  ---  write something to a file \n\
	logout ---  exit user \n\
	rm     ---  delete a directory or a file \n\
	exit   ---  exit this system\n");
}

int analyse(char *str)
{
	int  i;
	char temp[20];
	char *ptr_char;
	char *syscmd[]={"help","ls","cd","mkdir","touch","cat","write","rm","logout","exit","sysinfo","cls"};
	argc = 0;
	for(i = 0, ptr_char = str; *ptr_char != '\0'; ptr_char++)
	{
		if(*ptr_char != ' ')
		{
			while(*ptr_char != ' ' && (*ptr_char != '\0'))
				temp[i++] = *ptr_char++;
			argv[argc] = (char *)malloc(i+1);
			strncpy(argv[argc], temp, i);
			argv[argc][i] = '\0';
			argc++;
			i = 0;
			if(*ptr_char == '\0')
				break;
		}
	}
	if(argc != 0)
	{
		for(i = 0; (i < 12) && strcmp(argv[0], syscmd[i]); i++);
			return i;
	}
	else
		return 12;
	return 0;
}

void login()
{
	char userName[10];
	char passWord[10];
	while(1)
	{
		printf("login:");
		gets(userName);
        system("stty -echo");
		printf("passwd:");
		gets(passWord);
		system("stty echo");
		printf("\n");
		if(strcmp(userName,curUser.userName)==0&&strcmp(passWord,curUser.passWord)==0)
			break;
	}
}

void stopHandle(int sig)
{
    printf("\nPlease wait...,update resource\n");
    updateResource();
    exit(0);
}

void command(void)
{
	char cmd[20];
	do
	{
		pathSet();
		gets(cmd);
		switch(analyse(cmd))
		{
			case 0:
				help();
				break;
			case 1:
				list();
				break;
			case 2:
				cd(argv[1]);
				break;
			case 3:
				createFile(argv[1],1);
				break;
			case 4:
				createFile(argv[1],0);
				break;
			case 5:
				read(argv[1]);
				break;
			case 6:
				write(argv[1]);
				break;
			case 7:
				delete(argv[1]);
				break;
			case 8:
				updateResource();
				login();
				openFileSystem();
                command();
				break;
			case 9:
				updateResource();
				exit(0);
				break;
			case 10:
				systemInfo();
				break;
            case 11:
                system("clear");
				break;
			default:
				break;
		}
	}while(1);
}

int main(int argc,char **argv){
    signal(SIGINT,stopHandle);
	login();
	openFileSystem();
	command();
	return 0;
}






1.本题目为模拟UNIX文件系统来设计一个多用户多级目录的文件系统。 1)课程设计所利用的空间为1M的内存模拟外存文件系统存储空间)或用一个文件模拟一个磁盘分模拟外存文件系统存储空间。这1M内存分成512块,每块为512个字节,这512块就是文件系统总共的可用块数,文件系统的分配就是以块为单位来分配的,空闲块的管理利用位示图的方法来管理。申请1M的内存的方法可以利用malloc()等。 2)在构造文件系统空间时,不用做引导块;专用块中只包含对空闲块和空闲磁盘i节点进行管理的信息,即位示图和记录空闲磁盘i节点号的数组(该数组大小可设置为与磁盘i节点总数相等);要做磁盘i节点文件存储;不用做进程对换。注意:仔细计算,合理分配各域。 3)磁盘i节点可以利用在内存中生成链表或者数组的方法来生成,并且限制磁盘i节点数的最大值。同样内存活动i节点也可以利用链表的方法在内存中生成。 4)在往文件中写或者读的时候我们都是对内存内容进行读写。例如你在文件中写的时候,其实是对分配的文件块中对应的内存赋值。当程序运行结束的时候,文件内容都会丢失。我们这个文件系统只是一个模拟文件系统功能的虚拟文件系统。当然,若用一个文件模拟一个磁盘分模拟外存文件系统存储空间,那你在这个模拟系统中建立的文件内容就不会丢失了 本程序使用txt文件模拟磁盘分
第1章 系统概貌 1.1 历史 1.2 系统结构 1.3 用户看法 1.3.1 文件系统 1.3.2 处理环境 1.3.3 构件原语 1.4 操作系统服务 1.5 关于硬件的假设 1.5.1 中断与例外 1.5.2 处理机执行级 1.5.3 存储管理 1.6 本章小结 第2章 内核导言 2.1 UNIX操作系统的体系结构 2.2 系统概念介绍 2.2.1 文件子系统概貌 .2.2.2 进程 2.3 内核数据结构 2.4 系统管理 2.5 本章小结 2.6 习题 第3章 数据缓冲高速缓冲 3.1 缓冲头部 3.2 缓冲池的结构 3.3 缓冲的检索 3.4 读磁盘块与写磁盘块 3.5 高速缓冲的优点与缺点 3.6 本章小结 3.7 习题 第4章 文件的内部表示 4.1 索引节点 4.1.1 定义 4.1.2 对索引节点的存取 4.1.3 释放索引节点 4.2 正规文件结构 4.3 目录 4.4 路径名到索引节点的转换 4.5 超级块 4.6 为新文件分配索引节点 4.7 磁盘块的分配 4.8 其他文件类型 4.9 本章小结 4.10 习题 第5章 文件系统的系统调用 5.1 系统调用open 5.2 系统调用read 5.3 系统调用write 5.4 文件和记录的上锁 5.5 文件的输入/输出位置的调整—lseek 5.6 系统调用close 5.7 文件的建立 5.8 特殊文件的建立 5.9 改变目录及根 5.10 改变所有者及许可权方式 5.11 系统调用stat和fstat 5.12 管道 5.12.1 系统调用pipe 5.12.2 有名管道的打开 5.12.3 管道的读和写 5.12.4 管道的关闭 5.12.5 例 5.13 系统调用dup 5.14 文件系统的安装和拆卸 5.14.1 在文件路径名中跨越安装点 5.14.2 文件系统的拆卸 5.15 系统调用link 5.16 系统调用unlink 5.16.1 文件系统的一致性 5.16.2 竞争条件 5.17 文件系统的抽象 5.18 文件系统维护 5.19 本章小结 5.20 习题 第6章 进程结构 6.1 进程的状态和状态的转换 6.2 系统存储方案 6.2.1 6.2.2 页和页表 6.2.3 内核的安排 6.2.4 u 6.3 进程的上下文 6.4 进程上下文的保存 6.4.1 中断和例外 6.4.2 系统调用的接口 6.4.3 上下文切换 6.4.4 为废弃返回(abortive return)而保存上下文 6.4.5 在系统和用户地址空间之间拷贝数据 6.5 进程地址空间的管理 6.5.1 的上锁和解锁 6.5.2 的分配 6.5.3 附接到进程 6.5.4 大小的改变 6.5.5 的装入 6.5.6 的释放 6.5.7 与进程的断接 6.5.8 的复制 6.6 睡眠 6.6.1 睡眠事件及地址 6.6.2 算法sleep和wakeup 6.7 本章小结 6.8 习题 第7章 进程控制 7.1 进程的创建 7.2 软中断信号 7.2.1 软中断信号的处理 7.2.2 进程组 7.2.3 从进程发送软中断信号 7.3 进程的终止 7.4 等待进程的终止 7.5 对其他程序的引用 7.6 进程的用户标识号 7.7 改变进程的大小 7.8 shell程序 7.9 系统自举和进程init 7.10 本章小结 7.11 习题 第8章 进程调度和时间 8.1 进程调度 8.1.1 算法 8.1.2 调度参数 8.1.3 进程调度的例子 8.1.4 进程优先权的控制 8.1.5 公平共享调度 8.1.6 实时处理 8.2 有关时间的系统调用 8.3 时钟 8.3.1 重新启动时钟 8.3.2 系统的内部定时 8.3.3 直方图分析 8.3.4 记帐和统计 8.3.5 计时 8.4 本章小结 第9章 存储管理策略 9.1 对换 9.1.1 对换空间的分配 9.1.2 进程的换出 9.1.3 进程的换入 9.2 请求调页 9.2.1 请求调页的数据结构 9.2.2 偷页进程 9.2.3 页面错 9.2.4 在简单硬件支持下的请示调页系统 9.3 对换和请示调页的混合系统 9.4 本章小结 9.5 习题 第10章 输入/输出子系统 10.1 驱动程序接口 10.1.1 系统配置 10.1.2 系统调用与驱动程序接口 10.1.3 中断处理程序
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值