2020-04-06

以下是源代碼



#include <stdio.h>

#include <stdlib.h>

#include <malloc.h>

#define TRUE 1

#define FALSE 0

//作業(yè)數(shù)組大小

#define LEN 5

/*

**

** 各種調(diào)度算法模擬仿真(鏈?zhǔn)酱鎯Φ年犃袑崿F(xiàn)版):

** 短作業(yè)優(yōu)先調(diào)度算法 (SJF)肥矢、先來先服務(wù)調(diào)度算法 (FCFS)

** 時間片輪轉(zhuǎn)調(diào)度算法 (RR) 甘改、最高響應(yīng)比調(diào)度算法(HRRN)?

** Author:賈志洋

** version:1.0

** Create Time: 2020/4/05 22:09

** Modified Time:

*/

/*進(jìn)程PCB結(jié)點結(jié)構(gòu)體*/

typedef struct job

{

int PID; //進(jìn)程的PID

int arrival_time; //進(jìn)程到達(dá)系統(tǒng)時間

int require_time_slice; //要求服務(wù)時間

int used_time_slice; //已經(jīng)使用的時間片(短作業(yè)優(yōu)先用不到該值)

int ended_time; //進(jìn)程完成時間 十艾,初始值為-1忘嫉,表示進(jìn)程未完成,如果該進(jìn)程已經(jīng)完成則>=0

int waited_time; //等待時間康吵,等待時間=周轉(zhuǎn)時間-要求服務(wù)時間

int cycle_time; //周轉(zhuǎn)時間访递,周轉(zhuǎn)時間=結(jié)束時間-到達(dá)時間

float weight_cycle_time; //帶權(quán)周轉(zhuǎn)時間晦嵌,帶權(quán)周轉(zhuǎn)時間=周轉(zhuǎn)時間/要求服務(wù)時間

struct job * next; //所在隊列的下一個作業(yè)

}job;

/*作業(yè)隊列的結(jié)構(gòu)體*/

typedef struct linked_queue

{

job * front; //隊頭指向結(jié)點的指針

job * rear; //隊尾指向結(jié)點的指針

int count; //隊列當(dāng)前長度

}linked_queue;

//作業(yè)數(shù)組全局變量

struct job job_array[LEN];

//后備隊列

linked_queue * created_queue;

//就緒隊列

linked_queue * ready_queue;

//完成隊列

linked_queue * ended_queue;

//初始化作業(yè)數(shù)組的每個作業(yè)信息

void init_jobs();

//初始化各個隊列

void init_queues();

//打印菜單

void print_menu();

//短作業(yè)優(yōu)先調(diào)度算法 (SJF)

void sjf_jobs();

//先來先服務(wù)調(diào)度算法 (FCFS)

void fcfs_jobs();

//時間片輪轉(zhuǎn)調(diào)度算法 (RR)

void rr_jobs(int q);

//最高響應(yīng)比調(diào)度算法(HRRN)

void hrrn_jobs();

//打印輸出所有作業(yè)的各種時間平均值

void print_average_value();

//作業(yè)出隊列函數(shù)

job * de_queue(linked_queue * queue);

//返回隊頭作業(yè)(不出隊)

job * peek_queue(linked_queue * queue);

//計算該作業(yè)的各種時間

void record_job_time(job * record_job);

//作業(yè)結(jié)點入隊

void en_queue_node(linked_queue * queue,job * en_queue_pcb_node);

/*程序入口*/

int main()

{

//記錄用戶鍵盤輸入的選擇鍵

char user_opt;

while(1)

{

//初始化作業(yè)數(shù)組中每個作業(yè)

init_jobs();

//初始化各個隊列

init_queues();

//打印菜單

print_menu();

scanf("%c", &user_opt);

getchar();

switch(user_opt)

{

case '1' :

sjf_jobs();

break;

case '2':

fcfs_jobs();

break;

case '3':

rr_jobs(1);

break;

case '4':

rr_jobs(4);

break;

case '5':

hrrn_jobs();

break;

case 'q':

exit(0);

break;

}

}

return 0;

}

void print_menu()

{

printf("\n======================\n");

printf("按1鍵SJF \n");

printf("按2鍵FCFS\n");

printf("按3鍵RR時間片輪轉(zhuǎn)(q=1)\n");

printf("按3鍵RR時間片輪轉(zhuǎn)(q=4)\n");

printf("按3鍵HRRN\n");

printf("按q鍵退出 \n");

printf("您的選擇: \n");

printf("\n======================\n");

}

void init_jobs()

{

//根據(jù)題目要求的表格初始化每個進(jìn)程的信息(也可以通過控制臺輸入)

job_array[0].PID = 0; job_array[0].require_time_slice = 3; job_array[0].arrival_time = 0; job_array[0].ended_time =-1; job_array[0].used_time_slice = 0;

job_array[1].PID = 1; job_array[1].require_time_slice = 6; job_array[1].arrival_time = 2; job_array[1].ended_time =-1; job_array[1].used_time_slice = 0;

job_array[2].PID = 2; job_array[2].require_time_slice = 4; job_array[2].arrival_time = 4; job_array[2].ended_time =-1; job_array[2].used_time_slice = 0;

job_array[3].PID = 3; job_array[3].require_time_slice = 5; job_array[3].arrival_time = 6; job_array[3].ended_time =-1; job_array[3].used_time_slice = 0;

job_array[4].PID = 4; job_array[4].require_time_slice = 2; job_array[4].arrival_time = 8; job_array[4].ended_time =-1; job_array[4].used_time_slice = 0;

}

void init_queues()

{

//釋放原來的

free(created_queue);

free(ready_queue);

free(ended_queue);

//后備隊列

created_queue = (linked_queue*)malloc(sizeof(linked_queue));

//初始化隊列

created_queue->front = created_queue->rear = NULL;

//就緒隊列

ready_queue = (linked_queue*)malloc(sizeof(linked_queue));

//初始化隊列

ready_queue->front = ready_queue->rear = NULL;

//完成隊列

ended_queue = (linked_queue*)malloc(sizeof(linked_queue));

//初始化隊列

ended_queue->front = ended_queue->rear = NULL;

//將作業(yè)數(shù)組中所有作業(yè)放入后備隊列

int i;

for(i=0;i<LEN;i++)

en_queue_node(created_queue,&job_array[i]);

}

void record_job_time(job * record_job)

{

//計算該作業(yè)的各種時間

record_job->cycle_time = record_job->ended_time - record_job->arrival_time;

record_job->waited_time = record_job->cycle_time - record_job->require_time_slice;

record_job->weight_cycle_time = (float)record_job->cycle_time / (float)record_job->require_time_slice;

}

void print_average_value()

{

//平均周轉(zhuǎn)時間

float avg_cycle_time = 0;

//平均等待時間

float avg_waited_time = 0;

//平均帶權(quán)周轉(zhuǎn)時間

float avg_weight_cycle_time = 0;

//遍歷作業(yè)數(shù)組,求和值

int i;

for(i=0;i<LEN;i++)

{

avg_cycle_time += (float) job_array[i].cycle_time;

avg_waited_time += (float) job_array[i].waited_time;

avg_weight_cycle_time += job_array[i].weight_cycle_time;

}

//計算均值

avg_cycle_time = avg_cycle_time / (float) LEN;

avg_waited_time = avg_waited_time / (float) LEN;

avg_weight_cycle_time = avg_weight_cycle_time / (float) LEN;

printf("平均周轉(zhuǎn)時間:%05.2f平均等待時間:%05.2f平均帶權(quán)周轉(zhuǎn)時間:%05.2f\n",avg_cycle_time,avg_waited_time,avg_weight_cycle_time);

}

void fcfs_jobs()

{

//先來先服務(wù)調(diào)度算法

int current_time = 0;

//當(dāng)前運行的作業(yè)

job * running_job = NULL;

//后備隊列不為空 或 就緒隊列不為空 或 正在有作業(yè)運行? 則進(jìn)行調(diào)度

while (!is_queue_empty(created_queue)||!is_queue_empty(ready_queue)||running_job!=NULL)

{

//把后備隊列中力九,到達(dá)時間為當(dāng)前系統(tǒng)時間的作業(yè)掛入就緒隊列

while (!is_queue_empty(created_queue))

{

job * front_job = peek_queue(created_queue);

if (front_job->arrival_time==current_time)

{

//后備隊列出隊一個作業(yè)并掛入就緒隊列

en_queue_node(ready_queue,de_queue(created_queue) );

}

else

{

//一定要有else耍铜,表示后備隊列中的當(dāng)前隊頭作業(yè)的到達(dá)系統(tǒng)時間大于系統(tǒng)當(dāng)前時間,需要退出while循環(huán)

break;

}

}

//判斷當(dāng)前是否有進(jìn)程使用CPU

if (running_job == NULL)

{

//無作業(yè)使用CPU跌前,將就緒隊列隊頭出隊,去使用CPU

if (!is_queue_empty(ready_queue))

running_job = de_queue(ready_queue);

else

{

//為了增加程序的健壯性抵乓,可以用某些其它數(shù)據(jù)測試(本題目要求沒有出現(xiàn)這種情況)

//需要考慮伴挚,當(dāng)前就緒隊列為空,但后備隊列仍舊有未到達(dá)系統(tǒng)的作業(yè)灾炭,系統(tǒng)時間空轉(zhuǎn)1個時間片

printf("系統(tǒng)%d時刻就緒隊列空\n", current_time);

current_time++;

continue;

}

//printf("調(diào)度新的作業(yè)使用CPU:%d\n",running_job->PID);

}

else

{

//如果有作業(yè)正在使用CPU茎芋,判斷其使用CPU時間是否已經(jīng)滿足其要求服務(wù)時間

if (running_job->used_time_slice==running_job->require_time_slice)

{

//該作業(yè)要求服務(wù)時間已滿足

//記錄作業(yè)完成時間

running_job->ended_time = current_time;

//將該作業(yè)掛入完成隊列

en_queue_node(ended_queue,running_job);

//計算并存儲各種時間

record_job_time(running_job);

printf("調(diào)作業(yè)%d已完成,完成時間:%d\n",running_job->PID,running_job->ended_time);

//從就緒隊列調(diào)度新的作業(yè)使用CPU

if (!is_queue_empty(ready_queue))

running_job = de_queue(ready_queue);

else

running_job = NULL;

}

else

{

//空實現(xiàn)

}

}

//系統(tǒng)時間步進(jìn)

current_time++;

//當(dāng)前正在運行的作業(yè)的使用的時間片++

if (running_job!=NULL)

running_job->used_time_slice++;

}

printf("SJF的調(diào)度信息:\n");

//打印該調(diào)度算法的各種時間的平均值

print_average_value();

}

void sjf_jobs()

{

//請實現(xiàn)蜈出,SJF算法

}

void rr_jobs(int q)

{

//請實現(xiàn)田弥,時間片輪轉(zhuǎn)RR算法,傳入?yún)?shù)為時間片q的大小

}

void hrrn_jobs()

{

//請實現(xiàn) 铡原,最高響應(yīng)比優(yōu)先算法HRRN(非搶占)偷厦,

}

//作業(yè)結(jié)點入隊

void en_queue_node(linked_queue * queue,job * en_queue_pcb_node)

{

//將傳入的Job作業(yè)結(jié)點入隊

if (is_queue_empty(queue)){

queue->front = en_queue_pcb_node;

queue->rear = en_queue_pcb_node;

}else{

//隊列非空,

queue->rear->next = en_queue_pcb_node;

queue->rear =? en_queue_pcb_node;

}

}

//判斷隊列是否為空

int is_queue_empty(linked_queue * queue)

{

if ((queue->front==NULL)&&(queue->rear==NULL))

return TRUE;

else

return FALSE;

}

/*遍歷隊列燕刻,按順序?qū)㈥犃兄忻總€元素的值打印輸出*/

void show_queue_all_job(linked_queue * queue){

if (is_queue_empty(queue)){

printf("隊列為空只泼,遍歷結(jié)束\n");

return;

}

//游標(biāo)指針

job * cursor_pcb_pointer;

cursor_pcb_pointer = queue->front;

printf("---------------\n");

printf("隊列為:\n");

/*順序遍歷隊列每個結(jié)點*/

while (cursor_pcb_pointer!=NULL){

//打印當(dāng)前結(jié)點信息,

printf("結(jié)點PID:%d卵洗,時間片需求為:%d\n",cursor_pcb_pointer->PID,cursor_pcb_pointer->require_time_slice);

//后移游標(biāo)指針

cursor_pcb_pointer=cursor_pcb_pointer->next;

}

printf("---------------\n");

}

job * de_queue(linked_queue * queue)

{

job * return_job;

if (is_queue_empty(queue)){

printf("隊列為空请唱,無法出隊\n");

return NULL;

}

return_job = queue->front;

if (queue->front==queue->rear){

//只有一個結(jié)點時候

queue->front=queue->rear=NULL;

}else{

//多于一個結(jié)點時

queue->front = queue->front->next;

}

return_job->next = NULL;

return return_job;

}

//返回隊頭作業(yè),但不出隊

job * peek_queue(linked_queue * queue)

{

return queue->front;

}

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末过蹂,一起剝皮案震驚了整個濱河市十绑,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌酷勺,老刑警劉巖孽惰,帶你破解...
    沈念sama閱讀 221,888評論 6 515
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異鸥印,居然都是意外死亡勋功,警方通過查閱死者的電腦和手機(jī)坦报,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 94,677評論 3 399
  • 文/潘曉璐 我一進(jìn)店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來狂鞋,“玉大人片择,你說我怎么就攤上這事∩ё幔” “怎么了字管?”我有些...
    開封第一講書人閱讀 168,386評論 0 360
  • 文/不壞的土叔 我叫張陵,是天一觀的道長信不。 經(jīng)常有香客問我嘲叔,道長,這世上最難降的妖魔是什么抽活? 我笑而不...
    開封第一講書人閱讀 59,726評論 1 297
  • 正文 為了忘掉前任硫戈,我火速辦了婚禮,結(jié)果婚禮上下硕,老公的妹妹穿的比我還像新娘丁逝。我一直安慰自己,他們只是感情好梭姓,可當(dāng)我...
    茶點故事閱讀 68,729評論 6 397
  • 文/花漫 我一把揭開白布霜幼。 她就那樣靜靜地躺著,像睡著了一般誉尖。 火紅的嫁衣襯著肌膚如雪罪既。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 52,337評論 1 310
  • 那天铡恕,我揣著相機(jī)與錄音琢感,去河邊找鬼。 笑死没咙,一個胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的千劈。 我是一名探鬼主播祭刚,決...
    沈念sama閱讀 40,902評論 3 421
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼墙牌!你這毒婦竟也來了涡驮?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 39,807評論 0 276
  • 序言:老撾萬榮一對情侶失蹤喜滨,失蹤者是張志新(化名)和其女友劉穎捉捅,沒想到半個月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體虽风,經(jīng)...
    沈念sama閱讀 46,349評論 1 318
  • 正文 獨居荒郊野嶺守林人離奇死亡棒口,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 38,439評論 3 340
  • 正文 我和宋清朗相戀三年寄月,在試婚紗的時候發(fā)現(xiàn)自己被綠了。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片无牵。...
    茶點故事閱讀 40,567評論 1 352
  • 序言:一個原本活蹦亂跳的男人離奇死亡漾肮,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出茎毁,到底是詐尸還是另有隱情克懊,我是刑警寧澤,帶...
    沈念sama閱讀 36,242評論 5 350
  • 正文 年R本政府宣布七蜘,位于F島的核電站谭溉,受9級特大地震影響,放射性物質(zhì)發(fā)生泄漏橡卤。R本人自食惡果不足惜扮念,卻給世界環(huán)境...
    茶點故事閱讀 41,933評論 3 334
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望蒜魄。 院中可真熱鬧扔亥,春花似錦、人聲如沸谈为。這莊子的主人今日做“春日...
    開封第一講書人閱讀 32,420評論 0 24
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽伞鲫。三九已至粘茄,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間秕脓,已是汗流浹背柒瓣。 一陣腳步聲響...
    開封第一講書人閱讀 33,531評論 1 272
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機(jī)就差點兒被人妖公主榨干…… 1. 我叫王不留吠架,地道東北人芙贫。 一個月前我還...
    沈念sama閱讀 48,995評論 3 377
  • 正文 我出身青樓,卻偏偏與公主長得像傍药,于是被迫代替她去往敵國和親磺平。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點故事閱讀 45,585評論 2 359

推薦閱讀更多精彩內(nèi)容

  • #include #include #include <malloc.h> #define TRUE 1 #def...
    小正歪閱讀 159評論 0 0
  • 沒有輸出的學(xué)習(xí)拐辽,效率低下拣挪,索然無味,興趣容易被減弱俱诸。 趁著清明假期菠劝,我把初三的英語網(wǎng)課聽了一遍,有關(guān)于閱讀題技巧睁搭,...
    酷KIKI閱讀 136評論 0 0
  • 投射我兒在上網(wǎng)課期間赶诊,從心理和學(xué)習(xí)態(tài)度上能端正態(tài)度笼平,克服困難,安排好各科學(xué)習(xí)時間甫何,迎頭趕上出吹,不斷進(jìn)步,進(jìn)入班級前十...
    花開生兩面閱讀 74評論 0 0
  • 一個人的聲望是晉升的重要基礎(chǔ)辙喂。曾國藩潛心學(xué)術(shù)捶牢,熱心公益,在皇帝心目中形象比較清新端正巍耗,這是他迅速升官的重要背景秋麸。 ...
    六安姐閱讀 345評論 0 1
  • 如何遍歷一個對象? 在JS中可以通過高級for循環(huán)來遍歷對象一下代碼的含義:將制定對象中所有的屬性和方法的名稱取出...
    ItsYaeji閱讀 1,191評論 0 0