通用型操作系統課程設計
⑴ 跪求操作系統課程設計一份
; boot.asm: ANOS fat12 軟盤啟動代碼
; Larry Li, 2005.2.25
; 2005.3.19
; 整理注釋
PosBuf equ 0700h
StackTop equ 07BF0h
BootStart equ 07C00h
;下面是內核的載入地址
SegKernel equ 0100h
RootBufEnd equ 02h
DataStart equ 04h
CursorPos equ 10h
; BOOT 會被 BIOS 載入到 00007C00h 處
org 7C00h
; 代碼段
segment .text
; 16 位代碼
bits 16
; start: 首先是跳過必須的 FAT 信息表執行後面的程序
Start:
jmp short Main
; 補一個位元組的空指令
nop
; FAT12 信息
; 只是文件系統的描述信息
OEMName db 'ANOSDISK'
; 扇區大小(位元組),應為 512
BytesPerSector dw 512
; 簇的扇區數,應為 2 的冪,FAT12 為 1
SectsPerCluster db 1
; 保留扇區,FAT12/16 應為 1
ReservedSectors dw 1
; FAT 結構數目,一般為 2
NumberOfFats db 2
; 根目錄項目數,FAT12 為 224
MaxRootEntries dw 224
; 扇區總數,1.44M 軟盤為 2880
TotalSectors dw 2880
; 設備類型,1.44M 軟盤為 F0h
MediaDescriptor db 0f0h
; FAT 佔用扇區數,9
SectorsPerFat dw 9
; 磁軌扇區數,18
SectorsPerTrack dw 18
; 磁頭數,2
NumberOfHeads dw 2
; 隱藏扇區,默認為 0
HiddenSectors dd 0
; FAT32 使用,0
TotalSectorsBig dd 0
;; 下面的內容為 FAT12/16 所有,和 FAT32 不同
; MS-DOS 使用,0
BootDrive db 0
; Windows NT 使用,0
Reserved db 0
; 附加的可啟動標志,29h
ExtendSig db 029h
; 卷標序列號,00000000h
SerialNumber dd 00000000h
; 卷標,11 位元組,必須用空格( 20h )補齊
VolumeLabel db 'ANOS FLOPPY'
; 文件系統標志,
FileSystem db 'FAT12 '
; Main: BOOT 主程序
Main:
; 初始化運行環境
xor ax,ax
mov ss,ax
mov bp,BootStart
mov sp,StackTop
push ss
pop ds
; LoadRootDirSector: 讀取 FAT12 根目錄項目扇區
LoadRootDirSector:
push ss
pop es
; 計算 ROOT 啟始邏輯扇區
mov al,[BYTE bp+NumberOfFats]
; FAT 表數目
mul WORD [BYTE bp+SectorsPerFat]
; 乘上一個 FAT 表佔用的扇區數
add ax,WORD [BYTE bp+HiddenSectors]
; 加上隱藏的扇區數
add ax,WORD [BYTE bp+ReservedSectors]
; 加上保留的扇區數
push ax
mov WORD [BYTE bp-DataStart],ax
; AX ROOT 項目的啟始邏輯扇區, 保存
; 計算 ROOT 扇區數
mov ax,20h
mov cx,WORD [BYTE bp+MaxRootEntries]
mul cx
mov bx,WORD [BYTE bp+BytesPerSector]
add ax,bx
dec ax
div bx
mov cx,ax
; CX ROOT 扇區大小
add WORD [BYTE bp-DataStart],ax
; 更新數據區啟始邏輯扇區
mul bx
; AX ROOT 總扇區位元組大小
mov bx,PosBuf
; BX 緩存啟始地址
add ax,bx
; AX 緩存尾地址
mov WORD [BYTE bp-RootBufEnd],ax
; 保存尾地址
pop ax
; 取出 ROOT 項目啟始邏輯扇區
call ReadSectors
mov si,bx
; [ES:SI] 根目錄內容
; SearchRootDirSector: 在根目錄項目中搜索內核文件
SearchRootDirSector:
; [ES:SI] 為當前目錄項
; 其頭 11 個位元組為文件名稱
cmp [es:di],ch
; 如果目錄項的第一個位元組是0,這就是最後一個目錄項
jz NotFound
push si
; 保存 SI rep cmpsb 時 SI 會改變
mov cx,11
; 比較前 11 個位元組
mov di,FileName
; [DS:DI] 要載入的內核名稱
rep cmpsb
; 比較 [ES:SI] [DS:DI]
pop si
; 恢復 [ES:SI] 為當前查對的目錄項
je FoundKernel
add si,32
; [ES:SI] 指向下一個目錄項
; 每個目錄項 32 位元組
cmp si,WORD [BYTE bp-RootBufEnd]
; 是否到根目錄項目尾
jb SearchRootDirSector
; NotFound: 沒有發現內核的處理
NotFound:
mov si,msgNotFound
call PutChars
jmp ReBoot
; FoundKernel: 發現內核後處理
FoundKernel:
; [ES:SI] 內核文件目錄項
mov ax,[si+01ah]
push ax
; 內核文件啟始簇(低)地址
; 目錄項偏移 26(1ah) 為文件項目啟始簇低地址
; 偏移 20(14h) 為高地址
; 由 FAT12 只是 12 位簇地址, 低地址 16 位足以
xor dx,dx
mov es,dx
mov ax,WORD [BYTE bp+ReservedSectors]
; DX:AX 第一個 FAT 表的啟始邏輯扇區
mov bx,PosBuf
; [ES:BX] 讀盤緩存
mov cx,WORD [BYTE bp+SectorsPerFat]
; CX FAT 表扇區數
call ReadSectors
pusha
mov si,msgLoadKernel
call PutChars
popa
mov ax,SegKernel
mov es,ax
xor bx,bx
; [ES:BX] 讀盤緩存, 內核載入地址
pop ax
push ax
; 文件的第一個簇
; LoadKernel: 載入內核
LoadKernel:
; AX 當前簇
call ReadCluster
pop ax
; 取當前簇
add bx,0200h
; [ES:BX] 緩存地址增加 512 位元組(1 個扇區)
; 下面開始查 FAT12 表項目
; 所以對於簇 n 其項目位於 n / 2 * 3 處
; n / 2 * 3 = n / 2 + n
; n 為偶, 在低 12 位
; n 為奇, 在高 12 位
mov di,ax
; BP DI 文件簇 n
shr di,01h
; DI n / 2
pushf
; 保存標志位, 供以後奇偶處理
add di,ax
; DI n / 2 + n
add di,PosBuf
; DI 加上 FAT12 表的啟始地址
mov ax,[di]
; AX 一個 FAT12 組, 兩個簇號
popf
; 根據 n / 2 奇偶判定
jc ShiftRight4
and ax,0fffh
; 取低 12 位
jmp IsTheEnd
ShiftRight4:
mov cl,4
shr ax,cl
; 高 12 位, 所以右移 4 位
IsTheEnd:
cmp ax,0ff8h
; 比較, ff8h - fffh 表示簇鏈末尾
jae ExecKernel
; 載入完畢, 跳轉到內核地址
push ax
; 復制下一簇號
jmp LoadKernel
; ExecKernel: 運行內核
ExecKernel:
pusha
mov si,msgLoadKernelOK
call PutChars
popa
mov ah,3
xor bh,bh
int 10h
mov WORD [BYTE bp-CursorPos],dx
; 將當前游標位置寫入 7df0h 7df1h
;
push word SegKernel
push word 00h
; 入棧供返回指令跳轉
retf
; BadDisk: 顯示錯誤啟動信息,然後重啟
BadDisk:
mov si,msgDiskError
call PutChars
; ReBoot: 重啟
ReBoot:
mov si,msgAnyKey
call PutChars
xor ax,ax
int 16h
; 等待鍵盤按鍵
int 19h
; 重啟
; ReadCluster: 讀磁碟文件簇
; 讀數據簇 AX 到 [ES:BX]
; CarryFlag == 1 錯誤
ReadCluster:
; 顯示一個 .
push ax
mov ax,0e2eh
int 10h
pop ax
dec ax
dec ax
; 修正, 簇號 - 2
add ax, WORD [BYTE bp-DataStart]
; AX 數據的啟始邏輯扇區
xor dx,dx
mov cx,01h
; ReadSectors: 讀磁碟扇區
; 讀 CX 個邏輯扇區(地址 DX:AX)到 [ES:BX]
; CarryFlag == 1 錯誤
ReadSectors:
pusha
push cx ; 保存讀取扇區數
; 首先要將 DX:AX 邏輯扇區號轉換為[驅動器號][磁頭號][磁軌號][扇區號]
; 根據:磁碟總扇區 = 磁軌數 * 磁頭數 * 扇區數
; 邏輯扇區 = (磁軌號 * 磁頭數 + 磁頭號) * 扇區數 + 扇區號 - 1
; (注意:實際在磁軌的扇區號是從 1 開始計數的,其他號從 0 開始)
; 那麼:扇區號 = 邏輯扇區 % 磁軌的扇區數 + 1
; 同樣:含磁頭計算的磁軌號 = 邏輯扇區 / 磁軌的扇區數
; 除掉磁頭數,就是:磁軌號 = 含磁頭計算的磁軌號 / 磁頭數
; 所以:磁頭號 = 含磁頭計算的磁軌號 % 磁頭數
xchg ax,cx ; AX <=> CX
xchg ax,dx ; AX <=> DX
; AX:CX 邏輯扇區
xor dx,dx ; DX 清零
div WORD [BYTE bp+SectorsPerTrack] ; 除高位
; 計算得含磁頭計算的磁軌號的高位
xchg ax,cx ; 臨時保存到 CX
; 此時余數 DX 與 AX 組成新數繼續低位除
div WORD [BYTE bp+SectorsPerTrack] ; 除低位
; 余數 DX 為 0 開的扇區號
inc dx ; 修正為 1 開
xchg cx,dx ; CX <=> DX
; CX 為扇區號
; DX:AX 為含磁頭計算的磁軌號
div WORD [BYTE bp+NumberOfHeads] ; 繼續除
; AX 為磁軌號
; DX(DL) 為磁頭號
mov dh,dl
; DH 磁頭號
mov dl,[BYTE bp+BootDrive]
; DL 驅動器號
mov ch,al
; CX bit 8-15(CH) 磁軌低 8 位
ror ah,2
; CX bit 6-7(AH bit 6-7) 磁軌高 2 位
or cl,ah
; CX bit 0-5 扇區
pop ax
; AL 操作扇區數目
mov ah,02h
; AH 02h 讀磁碟扇區
int 13h
; BIOS 13h 調用
; int 13h BIOS 功能
; 參數
; AH = 0x02 讀磁碟扇區到內存
; AL 需要讀出的扇區數量
; CH 磁軌(柱面)號的低 8 位
; CL 開始扇區(0-5位),磁軌號高 2 位(6-7)
; DH 磁頭號
; DL 驅動器號
; ES:BX 指向數據緩存
; 返回
; 出錯置 CF 標志位
; AH 狀態 = 0x01
; AL 讀取的扇區數
jc BadDisk
popa
ret
; PutChars: 列印字元串
; 入口參數 si
PutChars:
lodsb
or al,al
jz short Done
mov ah,0eh
mov bx,07h
int 10h
jmp short PutChars
Done:
retn
TheEnd:
db 0
msgLoadKernel db 'Loading ANOS',0
msgLoadKernelOK db 'OK!',0Dh,0Ah,0
msgNotFound db 'Cannot found ANOS kernel!',0Dh,0Ah,0
msgDiskError db 'Disk Error!',0Dh,0Ah,0
msgAnyKey db 'Press any key to reboot...',0Dh,0Ah,0
; 將 BOOT 映象對齊到 512 個位元組
times 496-($-$$) db 0
FileName db 'ANOS SYS',0,0
BootPartition:
db 0
; 啟動標志
BootSignature dw 0AA55h ; BootSector signature
⑵ 操作系統課程設計的內容簡介
本書介紹了Linux操作系統機制,分析了部分Linux內核代碼,並列出了操作系統針對性的實驗;從Linux操作系統環境、系統調用、定時器、內核模塊、進程調度、虛擬存儲、文件系統,循序漸進到Linux內核的改動。Linux操作系統環境使用放在本書的附錄中,對於沒有學習過Linux操作系統命令的讀者來說,需要掌握這方面的知識。
另一方面,作者本身也是程序員,對程序設計過程中的「創造性」有一定的體會。建議讀者在使用本書時,大可不必循規蹈矩,讀者可以用自己的思路學習Linux內核,這樣既學到Linux源程序本身,更學到程序的「靈魂」。
⑶ 操作系統課程設計請高手們解決
呵呵,我這有個我們用的文件系統的,你看下能用不...基本上是C的代碼吧。
#include <stdio.h>
#include <memory.h>
#include <string>
#include <iostream>
using namespace std;
struct FCB
{
char fname[16]; //文件名
int type; //1代表普通文件2代表目錄文件0表示空文件
int size; //文件大小
int fatherBlockNum; //當前的父目錄盤塊號
int currentBlockNum; //當前的盤塊
void initialize()
{
strcpy(fname,"\0");
type = 0;
size =0;
fatherBlockNum = currentBlockNum = 0;
}
};
/*常量設置*/
const char* FilePath = "C:\\myfiles";
const int BlockSize = 512; //盤塊大小(可配置)
const int OPEN_MAX = 5; //能打開最多的文件數
const int BlockCount = BlockSize/sizeof(int); //盤塊數
const int DiskSize = BlockSize*BlockCount; //磁碟大小
const int BlockFcbCount = BlockSize/sizeof(FCB);//目錄文件的最多FCB數
//const int IOBUF_SIZE = 512;
//char IOBuffer[IOBUF_SIZE];
int OpenFileCount = 0;
struct OPENLIST //用戶文件打開表
{
int files; //當前打開文件數
FCB f[OPEN_MAX]; //FCB拷貝
OPENLIST()
{
files=0;
for(int i=0;i<OPEN_MAX;i++){
f[i].fatherBlockNum=-1;//為分配打開
f[i].type=0;
}
}
};
/*-------------目錄文件結構---------------*/
struct dirFile
{
struct FCB fcb[BlockFcbCount];
void init(int _FatherBlockNum,int _CurrentBlockNum,char *name)//父塊號,當前塊號,目錄名
{
strcpy(fcb[0].fname,name); //本身的FCB
fcb[0].fatherBlockNum=_FatherBlockNum;
fcb[0].currentBlockNum=_CurrentBlockNum;
fcb[0].type=2; //標記目錄文件
for(int i=1;i<BlockFcbCount;i++){
fcb[i].fatherBlockNum=_CurrentBlockNum; //標記為子項
fcb[i].type=0; // 標記為空白項
}
}
};
/**********************************************************************/
struct DISK
{
int FAT1[BlockCount]; //FAT1
int FAT2[BlockCount]; //FAT2
struct dirFile root; //根目錄
char data[BlockCount-3][BlockSize];
void format()
{
memset(FAT1,0,BlockCount); //FAT1
memset(FAT2,0,BlockCount); //FAT2
FAT1[0]=FAT1[1]=FAT1[2]=-2; //0,1,2盤塊號依次代表FAT1,FAT2,根目錄區
FAT2[0]=FAT2[1]=FAT2[2]=-2; //FAT作備份
root.init(2,2,"G:\\");//根目錄區
memset(data,0,sizeof(data));//數據區
}
};
/*-----------------全局變數--------------------------*/
FILE *fp; //磁碟文件地址
char * BaseAddr; //虛擬磁碟空間基地址
string currentPath="G:\\"; //當前路徑
int current=2; //當前目錄的盤塊號
string cmd; //輸入指令
struct DISK *osPoint; //磁碟操作系統指針
char command[16]; //文件名標識
struct OPENLIST* openlist; //用戶文件列表指針
/*-----------函數事先申明--------------------*/
int format();
int mkdir(char *sonfname);
int rmdir(char *sonfname);
int create(char *name);
int listshow();
int delfile(char *name);
int changePath(char *sonfname);
int write(char *name);
int exit();
int open(char *file);
int close(char *file);
int read(char *file);
/*------------初始化-----------------------*/
int format()
{
current = 2;
currentPath="G:\\"; //當前路徑
osPoint->format();//打開文件列表初始化
delete openlist;
openlist=new OPENLIST;
/*-------保存到磁碟上myfiles--------*/
fp = fopen(FilePath,"w+");
fwrite(BaseAddr,sizeof(char),DiskSize,fp);
fclose(fp);
printf("----------------------------------------------------------\n\n");
return 1;
}
/*-----------------------創建子目錄-------------------*/
int mkdir(char *sonfname)
{
//判斷是否有重名
//尋找空白子目錄項
//尋找空白盤塊號
//當前目錄下增加該子目錄項
//分配子目錄盤塊,並且初始化
//修改fat表
int i,temp,iFAT;
struct dirFile *dir; //當前目錄的指針
if(current==2)
dir=&(osPoint->root);
else
dir=(struct dirFile *)(osPoint->data [current-3]);
/*--------為了避免該目錄下同名文件夾--------*/
for(i = 1;i<BlockFcbCount;i++)
{
if(dir->fcb[i].type==2 && strcmp(dir->fcb[i].fname,sonfname)==0 )
{
printf("該文件夾下已經有同名的文件夾存在了!\n");
return 0;
}
}
//查找空白fcb序號
for(i=1;i<BlockFcbCount;i++)
{
if(dir->fcb[i].type==0)
break;
}
if(i==BlockFcbCount)
{
printf("該目錄已滿!請選擇新的目錄下創建!\n");
return 0;
}
temp=i;
for(i = 3;i < BlockCount;i++)
{
if(osPoint->FAT1[i] == 0)
break;
}
if(i == BlockCount)
{
printf("磁碟已滿!\n");
return 0;
}
iFAT=i;
/*-------------接下來進行分配----------*/
osPoint->FAT1[iFAT]=osPoint->FAT2[iFAT] = 2; //2表示分配給下級目錄文件
//填寫該分派新的盤塊的參數
strcpy(dir->fcb[temp].fname,sonfname);
dir->fcb[temp].type=2;
dir->fcb[temp].fatherBlockNum=current;
dir->fcb[temp].currentBlockNum=iFAT;
//初始化子目錄文件盤塊
dir=(struct dirFile*)(osPoint->data [iFAT-3]); //定位到子目錄盤塊號
dir->init (current,iFAT,sonfname);//iFAT是要分配的塊號,這里的current用來指要分配的塊的父塊號
printf("---------------------------------------------------------------\n\n");
return 1;
}
/*-------刪除當前目錄下的文件夾--------*/
int rmdir(char *sonfname)
{
//if(子目錄不存在) return error
//if(子目錄不是空文件夾) return error
//回收子目錄磁碟塊號b(修改fat)
//回收子目錄占據目錄項
int i,temp,j;//確保當前目錄下有該文件,並記錄下該FCB下標
struct dirFile *dir; //當前目錄的指針
if(current==2)
dir=&(osPoint->root);
else
dir=(struct dirFile *)(osPoint->data [current-3]);
for(i=1;i<BlockFcbCount;i++)
{ //查找該目錄文件
if(dir->fcb[i].type==2 && strcmp(dir->fcb[i].fname,sonfname)==0)
{
break;
}
}
temp=i;
if(i==BlockFcbCount)
{
printf("當前目錄下不存在該子目錄!\n");
return 0;
}
j = dir->fcb[temp].currentBlockNum;
struct dirFile *sonDir; //當前子目錄的指針
sonDir=(struct dirFile *)(osPoint->data [ j - 3]);
for(i=1;i<BlockFcbCount;i++) //查找子目錄是否為空目錄
{
if(sonDir->fcb[i].type!=0)
{
printf("該文件夾為非空文件夾,為確保安全,請清空後再刪除!\n");
return 0;
}
}
/*開始刪除子目錄操作*/
osPoint->FAT1[j] = osPoint->FAT2[j]=0; //fat清空
char *p=osPoint->data[j-3]; //格式化子目錄
memset(p,0,BlockSize);
dir->fcb[temp].initialize(); //回收子目錄占據目錄項
printf("---------------------------------------------------------------\n\n");
return 1;
}
/*-----------在當前目錄下創建文本文件---------------*/
int create(char *name)
{
int i,iFAT;//temp,
int emptyNum = 0,isFound = 0; //空閑目錄項個數
struct dirFile *dir; //當前目錄的指針
if(current==2)
dir=&(osPoint->root);
else
dir=(struct dirFile *)(osPoint->data [current-3]);
//查看目錄是否已滿
//為了避免同名的文本文件
for(i=1;i<BlockFcbCount;i++)
{
if(dir->fcb[i].type == 0 && isFound == 0)
{
emptyNum = i;
isFound = 1;
}
else if(dir->fcb[i].type==1 && strcmp(dir->fcb[i].fname,name)==0 )
{
printf("無法在同一目錄下創建同名文件!\n");
return 0;
}
}
if(emptyNum == 0)
{
printf("已經達到目錄項容納上限,無法創建新目錄!\n");
return 0;
}
//查找FAT表尋找空白區,用來分配磁碟塊號j
for(i = 3;i<BlockCount;i++)
{
if(osPoint->FAT1[i]==0)
break;
}
if(i==BlockCount)
{
printf("磁碟已滿!\n");
return 0;
}
iFAT=i;
/*------進入分配階段---------*/
//分配磁碟塊
osPoint->FAT1[iFAT] = osPoint->FAT2[iFAT] = 1;
/*-----------接下來進行分配----------*/
//填寫該分派新的盤塊的參數
strcpy(dir->fcb[emptyNum].fname,name);
dir->fcb[emptyNum].type=1;
dir->fcb[emptyNum].fatherBlockNum=current;
dir->fcb[emptyNum].currentBlockNum=iFAT;
dir->fcb[emptyNum].size =0;
char* p = osPoint->data[iFAT -3];
memset(p,'#',BlockSize);
printf("----------------------------------------------------------------\n\n");
return 1;
}
/*-------查詢子目錄------------*/
int listshow()
{
int i,DirCount=0,FileCount=0;
//搜索當前目錄
struct dirFile *dir; //當前目錄的指針
if(current==2)
dir=&(osPoint->root);
else
dir=(struct dirFile *)(osPoint->data [current-3]);
for(i=1;i<BlockFcbCount;i++)
{
if(dir->fcb[i].type==1)
{ //查找普通文件
FileCount++;
printf("%s 文本文件.\n",dir->fcb[i].fname);
}
if(dir->fcb[i].type==2)
{ //查找目錄文件
DirCount++;
printf("%s 文件夾.\n",dir->fcb[i].fname);
}
}
printf("\n該目錄下共有 %d 個文本文件, %d 個文件夾\n\n",FileCount,DirCount);
printf("--------------------------------------------------------\n\n");
return 1;
}
/*---------在當前目錄下刪除文件-----------*/
int delfile(char *name)
{
int i,temp,j;
//確保當前目錄下有該文件,並且記錄下它的FCB下標
struct dirFile *dir; //當前目錄的指針
if(current==2)
dir=&(osPoint->root);
else
dir=(struct dirFile *)(osPoint->data [current-3]);
for(i=1;i<BlockFcbCount;i++) //查找該文件
{
if(dir->fcb[i].type==1 && strcmp(dir->fcb[i].fname,name)==0)
{
break;
}
}
if(i==BlockFcbCount)
{
printf("當前目錄下不存在該文件!\n");
return 0;
}
//從打開列表中刪除
close(name);
temp=i;
/*開始刪除文件操作*/
j = dir->fcb [temp].currentBlockNum ; //查找盤塊號j
osPoint->FAT1[j]=osPoint->FAT2[j]=0; //fat1,fat2表標記為空白
char *p=osPoint->data[j - 3];
memset(p,0,BlockSize); //清除原文本文件的內容
dir->fcb[temp].initialize(); //type=0; //標記該目錄項為空文件
printf("------------------------------------------------------------\n\n");
return 1;
}
/*--------------進入當前目錄下的子目錄--------------*/
int changePath(char *sonfname)
{
struct dirFile *dir; //當前目錄的指針
if(current==2)
dir=&(osPoint->root);
else
dir=(struct dirFile *)(osPoint->data [current-3]);
/*回到父目錄*/
if(strcmp(sonfname,"..")==0)
{
if(current==2)
{
printf("你現已經在根目錄下!\n");
return 0;
}
current = dir->fcb[0].fatherBlockNum ;
currentPath = currentPath.substr(0,currentPath.size() - strlen(dir->fcb[0].fname )-1);
return 1;
}
/*進入子目錄*/
int i,temp;
//確保當前目錄下有該目錄,並且記錄下它的FCB下標
for(i = 1; i < BlockFcbCount; i++)
{ //查找該文件
if(dir->fcb[i].type==2 && strcmp(dir->fcb[i].fname,sonfname)==0 )
{
temp=i;
break;
}
}
if(i==BlockFcbCount)
{
printf("不存在該目錄!\n");
return 0;
}
//修改當前文件信息
current=dir->fcb [temp].currentBlockNum ;
currentPath = currentPath+dir->fcb [temp].fname +"\\";
printf("-------------------------------------------------------------\n\n");
return 1;
}
/*--------System exit---------------------*/
int exit()
{
//將所有文件都關閉
//保存到磁碟上C:\myfiles
fp=fopen(FilePath,"w+");
fwrite(BaseAddr,sizeof(char),DiskSize,fp);
fclose(fp);
//釋放內存上的虛擬磁碟
free(osPoint);
//釋放用戶打開文件表
delete openlist;
printf("---------------------------------------------------------\n\n");
return 1;
}
/*-------------在指定的文件里記錄信息---------------*/
int write(char *name)
{
int i;
char *startPoint,*endPoint;
//在打開文件列表中查找 file(還需要考慮同名不同目錄文件的情況!!!)
for(i=0;i<OPEN_MAX;i++)
{
if(strcmp(openlist->f [i].fname,name)==0 )
{
if(openlist->f[i].fatherBlockNum ==current)
{
break;
}
else
{
printf("該文件處於打開列表中,本系統只能改寫當前目錄下文件!\n");
return 0;
}
}
}
if(i==OPEN_MAX)
{
printf("該文件尚未打開,請先打開後寫入信息!!\n");
return 0;
}
int active=i;
int fileStartNum = openlist->f[active].currentBlockNum - 3 ;
startPoint = osPoint->data[fileStartNum];
endPoint = osPoint->data[fileStartNum + 1];
printf("請輸入文本以#號結束:\t");
char input;
while(((input=getchar())!='#'))
{
if(startPoint < endPoint-1)
{
*startPoint++ = input;
}
else
{
printf("達到單體文件最大容量!");
*startPoint++ = '#';
break;
}
}
return 1;
}
/*---------選擇一個打開的文件讀取信息----------*/
int read(char *file)
{
int i,fileStartNum;
char *startPoint,*endPoint;
//struct dirFile *dir;
//在打開文件列表中查找 file(還需要考慮同名不同目錄文件的情況!!!)
for(i=0;i<OPEN_MAX;i++)
{
if(strcmp(openlist->f [i].fname,file)==0 )
{
if(openlist->f[i].fatherBlockNum ==current)
{
break;
}
else
{
printf("該文件處於打開列表中,本系統只能閱讀當前目錄下文件!\n");
return 0;
}
}
}
if(i==OPEN_MAX)
{
printf("該文件尚未打開,請先打開後讀取信息!\n");
return 0;
}
int active=i;
//計算文件物理地址
fileStartNum = openlist->f[active].currentBlockNum - 3 ;
startPoint = osPoint->data[fileStartNum];
endPoint = osPoint->data[fileStartNum + 1];
//end_dir=(struct dirFile *)[BlockSize-1];
//q=(char *)end_dir;
printf("該文件的內容為: ");
while((*startPoint)!='#'&& (startPoint < endPoint))
{
putchar(*startPoint++);
}
printf("\n");
return 1;
}
/*當前目錄下添加一個打開文件*/
int open(char *file)//打開文件
{
int i,FcbIndex;
//確保沒有打開過該文件 = 相同名字 + 相同目錄
for(i=0;i<OPEN_MAX;i++)
{
if(openlist->f[i].type ==1 && strcmp(openlist->f [i].fname,file)==0 &&openlist->f[i].fatherBlockNum == current)
{
printf("該文件已經被打開!\n");
return 0;
}
}
//確保有空的打開文件項
if(openlist->files == OPEN_MAX)
{
printf("打開文件數目達到上限!無法再打開新文件.\n");
return 0;
}
//確保當前目錄下有該文件,並且記錄下它的FCB下標
struct dirFile *dir; //當前目錄的指針
if(current==2)
dir=&(osPoint->root);
else
dir=(struct dirFile *)(osPoint->data [current-3]);
for(i = 1;i< BlockFcbCount;i++)
{ //查找該文件
if(dir->fcb[i].type==1 && strcmp(dir->fcb[i].fname,file)==0 )
{
FcbIndex=i;
break;
}
}
if(i==BlockFcbCount)
{
printf("當前目錄下不存在該文件!\n");
return 0;
}
//裝載新文件進入打開文件列表,(FCB信息,文件數++) ??難道名字過不來?
openlist->f[OpenFileCount] = dir->fcb[FcbIndex]; //FCB拷貝
openlist->files ++;
printf("文件打開成功!\n");
OpenFileCount++;
return 1;
}
int close(char *file)
{
//釋放該文件所佔內存
//釋放用戶打開文件列表表項
int i;
//在打開文件列表中查找 file(還需要考慮同名不同目錄文件的情況!!!)
for(i=0;i<OPEN_MAX;i++)
{
if((openlist->f [i].type = 1)&&
(strcmp(openlist->f [i].fname,file)==0))
{
if(openlist->f[i].fatherBlockNum == current)
{
break;
}
else
{
printf("該文件已打開,但未在當前目錄下,無法關閉!\n");
return 0;
}
}
}
if(i==OPEN_MAX)
{
printf("該文件未在打開列表中!\n");
return 0;
}
int active=i;
openlist->files --;
openlist->f[active].initialize();
OpenFileCount--;
printf("該文件已關閉!\n");
return 1;
}
void main()
{
/*********************************************************************/
printf("-----Welcome To My Operate System Of File(FAT)-----\n");
//使用說明書
printf("\n 以下是使用說明書:\n");
printf("--------------------------------------------------------------\n");
printf("|| format :對磁碟格式化. || \n");
printf("|| exit :安全退出該文件系統,保存信息. || \n");
printf("|| mkdir dirname :創建子目錄. || \n");
printf("|| rmdir dirname :刪除子目錄. || \n");
printf("|| ls dirname :顯示當前目錄下信息. || \n");
printf("|| cd dirname :更改當前目錄. || \n");
printf("|| create filename :創建一個新文件,並且打開. || \n");
printf("|| write filename :選擇一個打開的文件寫入信息 || \n");
printf("|| read filename :選擇一個打開的文件讀取信息. || \n");
printf("|| rm filename :刪除文件. || \n");
printf("|| open filename :打開文件. || \n");
printf("|| close filename :關閉文件. || \n");
printf("-------------------------------------------------------------\n\n");
//創建用戶文件打開表
openlist=new OPENLIST;
//申請虛擬空間並且初始化
BaseAddr=(char *)malloc(DiskSize);
//虛擬磁碟初始化
osPoint=(struct DISK *)(BaseAddr);
//載入磁碟文件
if((fp=fopen(FilePath,"r"))!=NULL){
fread(BaseAddr,sizeof(char),DiskSize,fp);
printf("載入磁碟文件( %s )成功,現在可以進行操作了!\n\n",FilePath);
}
else{
printf("這是你第一次使用該文件管理系統!\t正在初始化...\n");
format();
printf("初始化已經完成,現在可以進行操作了!\n\n");
}
printf("--------------------------------------------------------------\n\n");
while(1){
cout<<currentPath;
cin>>cmd;
if(cmd=="format"){
format();
}
else if(cmd=="mkdir"){
cin>>command;
mkdir(command);
}
else if(cmd=="rmdir"){
cin>>command;
rmdir(command);
}
else if(cmd=="ls"){
listshow();
}
else if(cmd=="cd"){
cin>>command;
changePath(command);
}
else if(cmd=="create"){
cin>>command;
create(command);
}
else if(cmd=="write"){
cin>>command;
write(command);
}
else if(cmd=="read"){
cin>>command;
read(command);
}
else if(cmd=="rm"){
cin>>command;
delfile(command);
}
else if(cmd=="open"){
cin>>command;
open(command);
}
else if(cmd=="close"){
cin>>command;
close(command);
}
else if(cmd=="exit"){
exit();
break;
}
else cout<<"無效指令,請重新輸入:"<<endl;
}
printf("Thank you for using my file system!\n");
}
可以運行的哈~~
⑷ 操作系統課設。急急急~~~~~
1、了解UNIX的命令及使用格式,熟悉UNIX/LINUX的常用基本命令,練習並掌握UNIX提供的vi編輯版器來編譯C程序,學會利用權gcc、gdb編譯、調試C程序。
2、用fork( )創建一個進程,再調用exec( )用新的程序替換該子進程的內容,利用wait( )來控制進程執行順序。
還要任務書包括以下東西:
設計思想;
3)各模塊的偽碼演算法;
4)函數的調用關系圖;
5)測試結果;
6)設計總結;
⑸ 操作系統課程設計(linux)
我也遇到過這個問題,安裝的時候你沒有裝圖形用戶終端(似乎是叫回Xwindow)。之前有叫你打勾安答裝的。所以最後就只有命令行界面了(其實這個界面也可以解,但我不大會)。重回到開頭找到打勾選項去勾選相應圖形界面安裝!
⑹ 操作系統課程設計 (包括進程管理、進程的同步和互斥、存儲管理)
- 課程設計的計算機操作系統程序
課程概述
計算機操作系統是中央廣播電視大學計算機科學與技術專業(本科),系統設置必修課程。教學總時數72.4學分,開設一學期。前課程,計算機組成原理,面向對象編程和數據結構。
計算機操作系統課程是計算機專業的課程,通過學習,使學生掌握電腦作業系統的設計和組成的基本原則之一;計算機操作系統的基本概念和新的概念,術語和術語;了解計算機的發展,操作系統的功能和設計技巧和方法,基本操作使用最常用的計算機操作系統(DOS,Windows,UNIX或Linux)的。
?課程內容
主要內容包括:概述電腦的操作系統,作業管理,文件管理,存儲管理,輸入輸出設備管理,工藝和管理處理器,操作系統結構和編程。
二,系統的教學內容和教學要求
章概述操作系統的中
教學內容:
操作系統的定義和發展形成的操作系統和五個主要類型,操作系統五大功能特性的操作系統的性能,配置的操作系統,「生成」的概念
教學要求:
主:什麼是操作系統;知道五類和五功能的操作系統;
至少掌握:掌握操作系統的安裝,使用和維護的實際懷抱;
理解:如何理解一個初步的了解,熟悉和解剖學的人機交互界面的操作系統
任務的作業管理
教學內容如下:
的特點,人機界面的發展;操作系統的shell語言的第一,第二和第三代介面的發展特點,基本鍵盤命令和系統調用任務調度演算法; 教學要求:
主的人機界面設計
大師:掌握基本的作業系統人機界面的設計思路;
理解:傳統的介面界面
章文件管理的
教學內容:
文件管理任務和功能的操作系統文件的結構和分類的物理結構和邏輯結構的文件,文件目錄結構,文件訪問控制和安全機制,文件系統模型結構;
教學要求:
水平:基本的文件訪問控制和系統管理;
>掌握的文件系統目錄分類管理功能;
理解:文件系統的程序設計
的章內部存儲管理
教學內容:
內存分區,分頁,子段的管理理念;物理地址和邏輯地址內存「擴展」技術;存儲管理,支柱存儲管理的內存分配演算法的
教學的要求:
掌握基本配置:內存管理和調度方法;
主:主不同的分區存儲管理,分頁和分段方法;
有關:有效利用的內存空間
第五章輸入和輸出設備管理器的教學內容:
的輸入和輸出設備的功能分類;獨占的,共享的,虛擬裝置的管理功能;輸入和輸出設備的處理程序;管理策略的輸入和輸出設備;
教學要求:
法師:法師的輸入和輸出設備的管理特性;
法師:法師分類設計方法的輸入和輸出設備;
明白了:
編程元素的輸入和輸出設備處理程序第
教學內容的低級別的處理器管理:
操作系統的核心功能,「過程」的概念,過程的並發和並行的基本狀態的轉換的過程;進程調度演算法進程同步和互斥過程PV操作,「鎖」的概念;
教學要求:
大師:在操作系統內核運行的基本概念「過程「;
掌握的基本轉換過程中的狀態和特徵;
理解:操作系統
教學內容,進程調度演算法的編程方案的結構
BR />第七章:
操作分層的模塊化的系統結構設計和操作系統的測試;的
教學的要求:
本章教學基本要求:了解基本的設計思路和方法現代計算機操作系統
三,教學媒體
本課程使用的教學媒體:文字材料,視頻材料,網路教學和輔導。
1。文字材料
計算機操作系統(2)武企業萬元清華大學出版社
註:本課程實驗的主要教材。
文字教材過程中的主要傳播媒介。准備的文字材料,同時保持先進性,科學的學科體系,這兩種作業系統的理論,技術,實現了一體化的三個強調的能力。
2。視頻教材
該課程16節和視頻,每講50分鍾,講授的課程集中困難,科目匯總。為了幫助學生理解操作系統的整體概念和思想,伍啟元教授揚聲器。
當然,視頻與相應的文字材料,注重藝術表達播放視頻教材,教學形象化。
3。
在線教學網上教學和指導,咨詢與上述有機介質方面的作用:(1)釋放的教學和指導性文件,課程公告,咨詢,參考材料;(2)根據工程進度教學,心理咨詢聊天室發表的一篇文章「自我測試題(3)實時Q&A,一天到一天的課程論壇Q;(4)開展網上教師培訓與教學研討會。
文字材料的基礎上,對學生的學習,視頻教科書的補充文字材料,在線咨詢是一個方便的教學和學習方式的互動。總之,分工和各種媒體,讓學生有更大的自主學習空間,以方便學生自由選擇,自主學習,提高學生的自我學習能力。
教學安排建議
當然主要教科書和課程實驗教學安排建議
教學點,請根據中央電大統一安排課程,面對面輔導的要求,如表1所示。
表1的主要教科書和課程實驗教學安排建議
每周教學內容小時的實驗內容推薦小時
操作系統的教學安排概述
2操作系統定義了五種類型, 5 4
三人人機界面管理Linux的實踐准備1
四個工作管理任務調度4
五個文件管理的任務和功能的Linux操作系統命令的邏輯結構和物理結構4
7個存儲管理任務和功能2命令解釋器4
九編制2
八分分配存儲管理段4
分配的存儲管理作業調度模擬編程的六個文件10設備管理的任務和職能
11種設備,技術和管理存儲分配管理設計4
過程的定義和特徵4 13進程調度和通信進程調度模擬編程 p> 15操作系統級模塊結構僵局的產生和處理14 26 4
(總復習)4
共56條16
課程視頻內容,示於表2。
章教學內容表2視頻教材課程小時的視頻時間分配
操作系統提供了一個概述8小時4
運營管理8小時2
文件管理2
8小時的存儲管理8小時
5個設備管理器
6過程管理8小時10小時4
7操作系統的系統程序結構6小時0
56小時16
2在線咨詢在線咨詢內容
包括教學文件,課程輔導,網路教室。充分利用網路資源,和偶爾的在線課程相關的輔導材料,定期,根據教學在線輔導和考試Q&A活動,適當安排的需要。具體安排如下:
?
包括課程介紹,教師,教學大綱,教學設計,教學檔案。
?課程輔導
包括課程學習和答案,專題輔導,習題和答案,自我測試,評估說明,網上還提供了教師講課教案教學點的教學使用。
?網路課堂
包括直播課堂和IP課件。
基於網路的教學活動:中央廣播電視大學一般集中在每學期安排的實時在線輔導學生,教師的教學和研究活動。具體的時間表,每學期上發布的TVU的網上家園。
?論壇:每天的日常應答的過程中。
課程的課堂直播第一學期,通過教育電視台播出,安排四次直播課堂,每次50分鍾。的第一堂課3個教學點,難點的教學和演講後代表咨詢審查的輔導和考試說明的過程中反映的共性問題。直播課堂掛在網頁上的內容。
工作
課程形成性評估書,當然工作量。工作成績計入課程成績。中央電大的工作,不時抽查,檢查審查和完成作業。
課程考試,請參閱「中央廣播電視大學計算機操作系統課程評估的指示。建議
五,教學方法?教學建議
(1)計算機操作系統是一個實用的課程。其特點是概念多,涉及范圍廣。要求教學輔導深和混亂的概念來進行詳細說明,並詳細描述每章的重點,管理和控制的調度演算法技能。
(2)注重培養學生熟悉的操作系統,以及在維護操作系統的問題進行分析,並在實驗中解決問題的能力。
?建議
(1)從宏觀和微觀把握學習操作系統。在宏觀上,要認識到在計算機系統中的操作系統的地位清除操作系統的整體結構;微觀方面應把握的操作系統是管理計算機資源(過程中,處理器,內存,文件,設備),了解概念,原理和技術。
(2)操作系統是計算機技術和管理技術相結合的聯想日常生活學習重復熟悉的樣品管理實現運營系統的管理方法,以加深對問題的理解。
(3)要注意加強自我學習的能力,有能力實現這一目標的「學習」的文化。
⑺ 求一個操作系統課程設計
#include<iostream>
using namespace std;
#define MAX 10
struct task_struct
{
char name[10]; /*進程名稱*/
int number; /*進程編號*/
float come_time; /*到達時間*/
float run_begin_time; /*開始運行時間*/
float run_time; /*運行時間*/
float run_end_time; /*運行結束時間*/
int priority; /*優先順序*/
int order; /*運行次序*/
int run_flag; /*調度標志*/
}tasks[MAX];
int counter; /*實際進程個數*/
int fcfs(); /*先來先服務*/
int ps(); /*優先順序調度*/
int sjf(); /*短作業優先*/
int hrrn(); /*響應比高優先*/
int pinput(); /*進程參數輸入*/
int poutput(); /*調度結果輸出*/
void main()
{ int option;
pinput();
printf("請選擇調度演算法(0~4):\n");
printf("1.先來先服務\n");
printf("2.優先順序調度\n");
printf(" 3.短作業優先\n");
printf(" 4.響應比高優先\n");
printf(" 0.退出\n");
scanf("%d",&option);
switch (option)
{ case 0:
printf("運行結束。\n");
break;
case 1:
printf("對進程按先來先服務調度。\n\n");
fcfs();
poutput();
break;
case 2:
printf("對進程按優先順序調度。\n\n");
ps();
poutput();
break;
case 3:
printf("對進程按短作業優先調度。\n\n");
sjf();
poutput();
break;
case 4:
printf("對進程按響應比高優先調度。\n\n");
hrrn();
poutput();
break;
}
}
int fcfs() /*先來先服務*/
{
float time_temp=0;
int i;
int number_schel;
time_temp=tasks[0].come_time;
for(i=0;i<counter;i++)
{
tasks[i].run_begin_time=time_temp;
tasks[i].run_end_time=tasks[i].run_begin_time+tasks[i].run_time;
tasks[i].run_flag=1;
time_temp=tasks[i].run_end_time;
number_schel=i;
tasks[number_schel].order=i+1;
}
return 0;
}
int ps() /*優先順序調度*/
{
float temp_time=0;
int i=0,j;
int number_schel,temp_counter;
int max_priority;
max_priority=tasks[i].priority;
j=1;
while ((j<counter)&&(tasks[i].come_time==tasks[j].come_time))
{
if (tasks[j].priority>tasks[i].priority)
{
max_priority=tasks[j].priority;
i=j;
}
j++;
} /*查找第一個被調度的進程*/
/*對第一個被調度的進程求相應的參數*/
number_schel=i;
tasks[number_schel].run_begin_time=tasks[number_schel].come_time;
tasks[number_schel].run_end_time=tasks[number_schel].run_begin_time+tasks[number_schel].run_time;
tasks[number_schel].run_flag=1;
temp_time=tasks[number_schel].run_end_time;
tasks[number_schel].order=1;
temp_counter=1;
while (temp_counter<counter)
{
max_priority=0;
for(j=0;j<counter;j++)
{ if((tasks[j].come_time<=temp_time)&&(!tasks[j].run_flag))
if (tasks[j].priority>max_priority)
{
max_priority=tasks[j].priority;
number_schel=j;
}
} /*查找下一個被調度的進程*/
/*對找到的下一個被調度的進程求相應的參數*/
tasks[number_schel].run_begin_time=temp_time;
tasks[number_schel].run_end_time=tasks[number_schel].run_begin_time+tasks[number_schel].run_time;
tasks[number_schel].run_flag=1;
temp_time=tasks[number_schel].run_end_time;
temp_counter++;
tasks[number_schel].order=temp_counter;
}return 0;
}
int sjf() /*短作業優先*/
{
float temp_time=0;
int i=0,j;
int number_schel,temp_counter;
float run_time;
run_time=tasks[i].run_time;
j=1;
while ((j<counter)&&(tasks[i].come_time==tasks[j].come_time))
{
if (tasks[j].run_time<tasks[i].run_time)
{
run_time=tasks[j].run_time;
i=j;
}
j++;
} /*查找第一個被調度的進程*/
/*對第一個被調度的進程求相應的參數*/
number_schel=i;
tasks[number_schel].run_begin_time=tasks[number_schel].come_time;
tasks[number_schel].run_end_time=tasks[number_schel].run_begin_time+tasks[number_schel].run_time;
tasks[number_schel].run_flag=1;
temp_time=tasks[number_schel].run_end_time;
tasks[number_schel].order=1;
temp_counter=1;
while (temp_counter<counter)
{
for(j=0;j<counter;j++)
{
if((tasks[j].come_time<=temp_time)&&(!tasks[j].run_flag))
}
for(j=0;j<counter;j++)
{ if((tasks[j].come_time<=temp_time)&&(!tasks[j].run_flag))
if(tasks[j].run_time<run_time)
{run_time=tasks[j].run_time;
number_schel=j;
}
}
/*查找下一個被調度的進程*/
/*對找到的下一個被調度的進程求相應的參數*/
tasks[number_schel].run_begin_time=temp_time;
tasks[number_schel].run_end_time=tasks[number_schel].run_begin_time+tasks[number_schel].run_time;
tasks[number_schel].run_flag=1;
temp_time=tasks[number_schel].run_end_time;
temp_counter++;
tasks[number_schel].order=temp_counter;
}return 0;
}
int hrrn() /*響應比高優先*/
{ int j,number_schel,temp_counter;
float temp_time,respond_rate,max_respond_rate;
/*第一個進程被調度*/
tasks[0].run_begin_time=tasks[0].come_time;
tasks[0].run_end_time=tasks[0].run_begin_time+tasks[0].run_time;
temp_time=tasks[0].run_end_time;
tasks[0].run_flag=1;
tasks[0].order=1;
temp_counter=1;
/*調度其他進程*/
while(temp_counter<counter)
{
max_respond_rate=0;
for(j=1;j<counter;j++)
{
if((tasks[j].come_time<=temp_time)&&(!tasks[j].run_flag))
{ respond_rate=(temp_time-tasks[j].come_time)/tasks[j].run_time;
if (respond_rate>max_respond_rate)
{
max_respond_rate=respond_rate;
number_schel=j;
}
}
} /*找響應比高的進程*/
tasks[number_schel].run_begin_time=temp_time;
tasks[number_schel].run_end_time=tasks[number_schel].run_begin_time+tasks[number_schel].run_time;
temp_time=tasks[number_schel].run_end_time;
tasks[number_schel].run_flag=1;
temp_counter+=1;
tasks[number_schel].order=temp_counter;
}
return 0;
}
int pinput() /*進程參數輸入*/
{ int i;
printf("please input the process counter:\n");
scanf("%d",&counter);
for(i=0;i<counter;i++)
{ printf("******************************************\n");
printf("please input the process of %d th :\n",i+1);
printf("please input the name:\n");
scanf("%s",tasks[i].name);
printf("please input the number:\n");
scanf("%d",&tasks[i].number);
printf("please input the come_time:\n");
scanf("%f",&tasks[i].come_time);
printf("please input the run_time:\n");
scanf("%f",&tasks[i].run_time);
printf("please input the priority:\n");
scanf("%d",&tasks[i].priority);
tasks[i].run_begin_time=0;
tasks[i].run_end_time=0;
tasks[i].order=0;
tasks[i].run_flag=0;
}
return 0;
}
int poutput() /*調度結果輸出*/
{
int i;
float turn_round_time=0,f1,w=0;
printf("name number come_time run_time run_begin_time run_end_time priority order turn_round_time\n");
for(i=0;i<counter;i++)
{
f1=tasks[i].run_end_time-tasks[i].come_time;
turn_round_time+=f1;
w+=(f1/tasks[i].run_time);
printf(" %s, %d, %5.3f, %5.3f, %5.3f, %5.3f, %d, %d, %5.3f\n",tasks[i].name,tasks[i].number,tasks[i].come_time,tasks[i].run_time,tasks[i].run_begin_time,tasks[i].run_end_time,tasks[i].priority,tasks[i].order,f1);
}
printf("average_turn_round_timer=%5.2f\n",turn_round_time/counter);
printf("weight_average_turn_round_timer=%5.2f\n",w/counter);
return 0;
}
如果對您有幫助,請記得採納為滿意答案,謝謝!祝您生活愉快!
⑻ 求操作系統課程設計
#include<iostream>
using namespace std;
#define MAX 10
struct task_struct
{
char name[10]; /*進程名稱*/
int number; /*進程編號*/
float come_time; /*到達時間*/
float run_begin_time; /*開始運行時間*/
float run_time; /*運行時間*/
float run_end_time; /*運行結束時間*/
int priority; /*優先順序*/
int order; /*運行次序*/
int run_flag; /*調度標志*/
}tasks[MAX];
int counter; /*實際進程個數*/
int fcfs(); /*先來先服務*/
int ps(); /*優先順序調度*/
int sjf(); /*短作業優先*/
int hrrn(); /*響應比高優先*/
int pinput(); /*進程參數輸入*/
int poutput(); /*調度結果輸出*/
void main()
{ int option;
pinput();
printf("請選擇調度演算法(0~4):\n");
printf("1.先來先服務\n");
printf("2.優先順序調度\n");
printf(" 3.短作業優先\n");
printf(" 4.響應比高優先\n");
printf(" 0.退出\n");
scanf("%d",&option);
switch (option)
{ case 0:
printf("運行結束。\n");
break;
case 1:
printf("對進程按先來先服務調度。\n\n");
fcfs();
poutput();
break;
case 2:
printf("對進程按優先順序調度。\n\n");
ps();
poutput();
break;
case 3:
printf("對進程按短作業優先調度。\n\n");
sjf();
poutput();
break;
case 4:
printf("對進程按響應比高優先調度。\n\n");
hrrn();
poutput();
break;
}
}
int fcfs() /*先來先服務*/
{
float time_temp=0;
int i;
int number_schel;
time_temp=tasks[0].come_time;
for(i=0;i<counter;i++)
{
tasks[i].run_begin_time=time_temp;
tasks[i].run_end_time=tasks[i].run_begin_time+tasks[i].run_time;
tasks[i].run_flag=1;
time_temp=tasks[i].run_end_time;
number_schel=i;
tasks[number_schel].order=i+1;
}
return 0;
}
int ps() /*優先順序調度*/
{
float temp_time=0;
int i=0,j;
int number_schel,temp_counter;
int max_priority;
max_priority=tasks[i].priority;
j=1;
while ((j<counter)&&(tasks[i].come_time==tasks[j].come_time))
{
if (tasks[j].priority>tasks[i].priority)
{
max_priority=tasks[j].priority;
i=j;
}
j++;
} /*查找第一個被調度的進程*/
/*對第一個被調度的進程求相應的參數*/
number_schel=i;
tasks[number_schel].run_begin_time=tasks[number_schel].come_time;
tasks[number_schel].run_end_time=tasks[number_schel].run_begin_time+tasks[number_schel].run_time;
tasks[number_schel].run_flag=1;
temp_time=tasks[number_schel].run_end_time;
tasks[number_schel].order=1;
temp_counter=1;
while (temp_counter<counter)
{
max_priority=0;
for(j=0;j<counter;j++)
{ if((tasks[j].come_time<=temp_time)&&(!tasks[j].run_flag))
if (tasks[j].priority>max_priority)
{
max_priority=tasks[j].priority;
number_schel=j;
}
} /*查找下一個被調度的進程*/
/*對找到的下一個被調度的進程求相應的參數*/
tasks[number_schel].run_begin_time=temp_time;
tasks[number_schel].run_end_time=tasks[number_schel].run_begin_time+tasks[number_schel].run_time;
tasks[number_schel].run_flag=1;
temp_time=tasks[number_schel].run_end_time;
temp_counter++;
tasks[number_schel].order=temp_counter;
}return 0;
}
int sjf() /*短作業優先*/
{
float temp_time=0;
int i=0,j;
int number_schel,temp_counter;
float run_time;
run_time=tasks[i].run_time;
j=1;
while ((j<counter)&&(tasks[i].come_time==tasks[j].come_time))
{
if (tasks[j].run_time<tasks[i].run_time)
{
run_time=tasks[j].run_time;
i=j;
}
j++;
} /*查找第一個被調度的進程*/
/*對第一個被調度的進程求相應的參數*/
number_schel=i;
tasks[number_schel].run_begin_time=tasks[number_schel].come_time;
tasks[number_schel].run_end_time=tasks[number_schel].run_begin_time+tasks[number_schel].run_time;
tasks[number_schel].run_flag=1;
temp_time=tasks[number_schel].run_end_time;
tasks[number_schel].order=1;
temp_counter=1;
while (temp_counter<counter)
{
for(j=0;j<counter;j++)
{
if((tasks[j].come_time<=temp_time)&&(!tasks[j].run_flag))
{ run_time=tasks[j].run_time;number_schel=j;break;}
}
for(j=0;j<counter;j++)
{ if((tasks[j].come_time<=temp_time)&&(!tasks[j].run_flag))
if(tasks[j].run_time<run_time)
{run_time=tasks[j].run_time;
number_schel=j;
}
}
/*查找下一個被調度的進程*/
/*對找到的下一個被調度的進程求相應的參數*/
tasks[number_schel].run_begin_time=temp_time;
tasks[number_schel].run_end_time=tasks[number_schel].run_begin_time+tasks[number_schel].run_time;
tasks[number_schel].run_flag=1;
temp_time=tasks[number_schel].run_end_time;
temp_counter++;
tasks[number_schel].order=temp_counter;
}return 0;
}
int hrrn() /*響應比高優先*/
{ int j,number_schel,temp_counter;
float temp_time,respond_rate,max_respond_rate;
/*第一個進程被調度*/
tasks[0].run_begin_time=tasks[0].come_time;
tasks[0].run_end_time=tasks[0].run_begin_time+tasks[0].run_time;
temp_time=tasks[0].run_end_time;
tasks[0].run_flag=1;
tasks[0].order=1;
temp_counter=1;
/*調度其他進程*/
while(temp_counter<counter)
{
max_respond_rate=0;
for(j=1;j<counter;j++)
{
if((tasks[j].come_time<=temp_time)&&(!tasks[j].run_flag))
{ respond_rate=(temp_time-tasks[j].come_time)/tasks[j].run_time;
if (respond_rate>max_respond_rate)
{
max_respond_rate=respond_rate;
number_schel=j;
}
}
} /*找響應比高的進程*/
tasks[number_schel].run_begin_time=temp_time;
tasks[number_schel].run_end_time=tasks[number_schel].run_begin_time+tasks[number_schel].run_time;
temp_time=tasks[number_schel].run_end_time;
tasks[number_schel].run_flag=1;
temp_counter+=1;
tasks[number_schel].order=temp_counter;
}
return 0;
}
int pinput() /*進程參數輸入*/
{ int i;
printf("please input the process counter:\n");
scanf("%d",&counter);
for(i=0;i<counter;i++)
{ printf("******************************************\n");
printf("please input the process of %d th :\n",i+1);
printf("please input the name:\n");
scanf("%s",tasks[i].name);
printf("please input the number:\n");
scanf("%d",&tasks[i].number);
printf("please input the come_time:\n");
scanf("%f",&tasks[i].come_time);
printf("please input the run_time:\n");
scanf("%f",&tasks[i].run_time);
printf("please input the priority:\n");
scanf("%d",&tasks[i].priority);
tasks[i].run_begin_time=0;
tasks[i].run_end_time=0;
tasks[i].order=0;
tasks[i].run_flag=0;
}
return 0;
}
int poutput() /*調度結果輸出*/
{
int i;
float turn_round_time=0,f1,w=0;
printf("name number come_time run_time run_begin_time run_end_time priority order turn_round_time\n");
for(i=0;i<counter;i++)
{
f1=tasks[i].run_end_time-tasks[i].come_time;
turn_round_time+=f1;
w+=(f1/tasks[i].run_time);
printf(" %s, %d, %5.3f, %5.3f, %5.3f, %5.3f, %d, %d, %5.3f\n",tasks[i].name,tasks[i].number,tasks[i].come_time,tasks[i].run_time,tasks[i].run_begin_time,tasks[i].run_end_time,tasks[i].priority,tasks[i].order,f1);
}
printf("average_turn_round_timer=%5.2f\n",turn_round_time/counter);
printf("weight_average_turn_round_timer=%5.2f\n",w/counter);
return 0;
}
⑼ 操作系統課程設計
最近沒什麼寫日記,想寫,但是對於感情方面的寫多了沒意思,變得庸俗。於是,我決定來一個科學的日誌。下面就寫寫我在操作系統那門課中的一個實驗:銀行家演算法。自從學了java,在我對游戲和網路情有獨鍾的基礎上,我拋棄了c語言,因此,這個實驗我是用java來編寫的。線程我沒學,所以就簡單地寫幾個輸入,然後得出結果。
銀行家演算法大家懂嗎?我想,我們學院的都應該懂的。簡單地來講,就是假設系統有n種資源,每種資源有m個數量。又假設有k個進程。如果某進程要取得一些資源則系統首先測試是否滿足資源請求要求,如果滿足,則嘗試分配,接著就判斷分配後系統有沒有發生死鎖,有,就還原,沒有就繼續。如果某進程要求進入內存,則系統要判斷所有進程的請求資源數有沒有超過可用資源,有則不許建立,沒有就可以建立該進程。
花了幾個小時(其實大概一個小時就能搞定,不過可能困的原因,有兩個錯誤沒有看出來。我在此要提醒大家,編寫程序的格式非常重要,不然檢查錯誤是在很難。),終於寫完程序和報告。下面就貼上我的代碼吧。
/*
* 操作系統實驗:
* 《銀行家演算法》本程序參考課本的例子,資源種數為3.如果要求更多可作相應更改。
*/
/**
*
* @author Kevin 華南農業大學
*/
//銀行家演算法,此為Banker類。
import java.util.ArrayList;
import java.util.Random;
public class Banker {
static int[] available = {10,5,7}; //各個資源可用的數量。
static ArrayList processM = new ArrayList(); //線性表,裡面裝的是進程。
public static void main(String[] args){ //主函數,調試用。
Process p1 = new Process(7,5,3);
Process p2 = new Process(3,2,2);
Process p3 = new Process(9,0,2);
Process p4 = new Process(2,2,2);
Process p5 = new Process(4,3,3);
processM.add(p1);
processM.add(p2);
processM.add(p3);
processM.add(p4);
processM.add(p5);
while(!p1.isOK() || !p2.isOK() || !p3.isOK() || !p4.isOK() || !p5.isOK()){ //進程都還有沒滿足的就繼續申請。
p1 = (Process)processM.get(0);
p2 = (Process)processM.get(1);
p3 = (Process)processM.get(2);
p4 = (Process)processM.get(3);
p5 = (Process)processM.get(4);
if(!p1.isOK())
allocation(p1.request(),p1,0); //申請資源,以下同。
if(!p2.isOK())
allocation(p2.request(),p2,1);
if(!p3.isOK())
allocation(p3.request(),p3,2);
if(!p4.isOK())
allocation(p4.request(),p4,3);
if(!p5.isOK())
allocation(p5.request(),p5,4);
}
}
public static boolean allocation(int[] rq ,Process process,int n){ //進程請求分配函數,
if(process.have[0] + rq[0] > process.claim[0] || process.have[1] + rq[1] > process.claim[1] || process.have[2] + rq[2] > process.claim[2]){
System.out.println("申請失敗。"+ (n+1)); //如果請求的資源比最大需求大,則申請失敗。
return false;
}
else{
if(rq[0] > available[0] || rq[0] > available[0] || rq[0] > available[0]){
//如果要求的資源暫時不夠,則先掛起。
}
else{
process.have[0] = process.have[0] + rq[0];
process.have[1] = process.have[1] + rq[1];
process.have[2] = process.have[2] + rq[2];
available[0] = available[0]-rq[0];
available[1] = available[1]-rq[1];
available[2] = available[2]-rq[2];
processM.add(n, process);
processM.remove(n+1);
}
if(safe()){ //如果安全,則分配成功。
System.out.println("申請成功。"+"進程"+ (n+1)+"已獲得資源分別為:"+ process.have[0]+" "+process.have[1]+" "+process.have[2]);
return true;
//如果安全,那資源被該進程利用。
}
else{
process.have[0] = process.have[0] - rq[0];
process.have[1] = process.have[1] - rq[1];
process.have[2] = process.have[2] - rq[2];
available[0] = available[0]+ rq[0];
available[1] = available[1]+ rq[1];
available[2] = available[2]+ rq[2];
processM.add(n, process);
processM.remove(n+1);
System.out.println("申請失敗。" + (n+1)); //不安全,則申請失敗.
return false;
//如果不安全,則還原,並且掛起該進程。
}
}
}
public static boolean safe(){ //判斷分配後是否安全。
ArrayList rest = new ArrayList(processM);
Process test ;
int num = rest.size();
int found = num*num;
while(found > 0 && !rest.isEmpty()){
test = (Process)rest.remove(0);
if(test.claim[0] - test.have[0] <= available[0] && test.claim[1] - test.have[1] <= available[1] && test.claim[2] - test.have[2] <= available[2] ){
available[0] = available[0] + test.have[0];
available[1] = available[1] + test.have[1];
available[2] = available[2] + test.have[2];
}
else {
rest.add(test);
}
found--;
}
if(rest.isEmpty()){
return true;
}
else
return false;
}
}
class Process{ //此類為進程類,描述的是一個進程。
int[] claim =new int[3]; //這個進程需要的資源數。
int[] have = new int[3];
public Process(int n1,int n2,int n3){ //初始化進程
claim[0] = n1;
claim[1] = n2;
claim[2] = n3;
have[0] = 0;
have[1] = 0;
have[2] = 0;
}
public boolean isOK(){ //判斷這個進程得到滿足沒有。
if(have[0] == claim[0] && have[1] == claim[1] && have[2] == claim[2]){
return true;
}
else return false;
}
public int[] request(){ //這個函數隨機生成3個數,作為某個進程的請求。
Random random = new Random(); //實例化隨機對象。
int[] num = new int[3];
num[0] = random.nextInt(10);
System.out.println(num[0]);
num[1] = random.nextInt(10);
System.out.println(num[1]);
num[2] = random.nextInt(10);
System.out.println(num[2]);
return num;
}
}