Linux程式設計:模擬程式排程演算法
稍稍有點作業系統基礎的朋友應該知道程式的排程演算法,在這裡Koala還是給大家略微介紹一下接下來將要用到的幾種演算法:
- 先來先服務(FCFS)
採用FCFS排程,先請求CPU的程式會先分配到CPU。
使用FCFS排程的等待時間通常較長,CPU利用率也會較低 - 最短作業優先排程(SJF)
採用SJF排程會選擇具有最短CPU執行時間的程式分配CPU使用權。如果兩個程式的CPU區間相同,則按照FCFS來進行選擇。
SJF排程可以證明是最佳的,它降低了平均等待時間。 - 輪轉法排程(RR)
RR排程將CPU時間分為較小的時間片,排程程式迴圈就緒佇列。為每一個程式分配不超過一個時間片的CPU。
RR排程專門用於分時系統。 - 優先順序排程
每一個程式都有一個優先順序與其關聯,具有最高優先順序的程式會分配到CPU。
優先順序排程的一個主要問題是優先順序較低的程式會產生飢餓現象。
整個程式設計思路按照如下進行:
建立主執行緒,主執行緒建立子執行緒,子執行緒有一個虛擬PCB
主執行緒建立20個子執行緒,分別實現FCFS排程、SJF排程、RR排程、優先順序排程,並且計算每個排程的平均等待時間。
對於每個子執行緒,在其執行期間,輸出其佔用的時間標號(例如,第3個執行緒佔用了第10秒的CPU時間,輸出為:“Thread3:10”)。
下面是整個的程式碼(僅供參考):
#include<stdio.h>
#include<stdlib.h>
#include<sys/types.h>
#include<unistd.h>
#include<pthread.h>
#include<time.h>
#include<iostream>
#define Thread_Num 20
using namespace std;
pthread_mutex_t Device_mutex ;
//Virtual PCB of threads
struct VirtualPCB
{
int tid;
int priority;
int waittime;
int runtime;
int arrivetime;
int visited;
int tempruntime;
public:
int gettid()
{
return tid;
}
int getwaittime()
{
return waittime;
}
int getpriority()
{
return priority;
}
int getruntime()
{
return runtime;
}
int getarrivetime()
{
return arrivetime;
}
void setvisit(int a)
{
visited=a;
}
int getvisit()
{
return visited;
}
int gettempruntime()
{
return tempruntime;
}
void setwaittime(int n)
{
waittime = n;
}
void settempruntime(int n)
{
tempruntime = tempruntime - n;
}
}TCB[Thread_Num];
//Function to initial virtual PCB
void t_init()
{
int n;
srand(time(NULL));
for(n =0;n<Thread_Num;n++)
{
TCB[n].tid = n + 1;//用執行緒建立序號作為虛擬程式id
//用隨機數隨機產生虛擬PCB的值
TCB[n].priority = 1 + rand()%19;
TCB[n].runtime = 1 + rand()%19;
TCB[n].arrivetime = 0;//模擬時,預設程式按建立順序依次在0時刻到達
TCB[n].waittime = 0;
TCB[n].visited =0;
TCB[n].tempruntime = TCB[n].runtime;
}
}
//Threads run function
void *t_print(void *arg)
{
int n = *(int *)arg;//get argument
while(1)
{
pthread_mutex_lock(&Device_mutex);
printf("Thread_%-2d: ",n);
printf("tid:%-2d priority:%-2d runtime:%-2d \n",TCB[n-1].gettid(),TCB[n-1].priority,TCB[n-1].runtime);
pthread_mutex_unlock(&Device_mutex);
sleep(1);
break;
}
//printf("Error %d\n",n);
pthread_exit(0);
}
//First come first service schedule function
void FCFS()
{
cout<<"-----------FCFS:"<<endl;
int i,j;
int start = 0;
float waittime = 0;
float avwait = 0;
for(i=0;i<Thread_Num/2;i++)
{
for(j=0;j<Thread_Num;j++){
if(TCB[j].getarrivetime()==i && TCB[j].getvisit()==0){
printf("Thread: %-2d Start: %-3d Runtime: %-2d\n",TCB[j].gettid(),start,TCB[j].getruntime());
waittime = waittime + (float)start;
start = start + TCB[j].getruntime();
TCB[j].setvisit(1);
}
}
}
avwait = waittime / (float)Thread_Num;
printf("Total waitting time : %f\n",waittime);
printf("Average waitting time : %f\n",avwait);
}
//Shortest job first schedule function
void SJF()
{
for(int k=0 ;k<Thread_Num;k++)
{
TCB[k].setvisit(0);
}
cout<<"-------------SJF:"<<endl;
int i,j;
int start = 0;
float waittime = 0;
float avwait = 0;
for(i=1;i<Thread_Num;i++)
{
for(j=0;j<Thread_Num;j++){
if(TCB[j].getruntime()==i && TCB[j].getvisit()==0){
printf("Thread: %-2d Start: %-3d Runtime: %-2d\n",TCB[j].gettid(),start,TCB[j].getruntime());
waittime = waittime + (float)start;
start = start + TCB[j].getruntime();
TCB[j].setvisit(1);
}
}
}
avwait = waittime / (float)Thread_Num;
printf("Total waitting time : %f\n",waittime);
printf("Average waitting time : %f\n",avwait);
}
//Round R schedule function
void RR(int r)
{
cout<<"--------------RR:"<<endl;
int start = 0;
float waittime = 0;
float avwait = 0;
for(int i=0;i<Thread_Num;i++)
{
int totaltime = totaltime + TCB[i].getruntime();
TCB[i].setvisit(0);
}
for(int j=0;j<20*Thread_Num;j=j+r)
{
int k = (j%(20*r))/r;
if(TCB[k].gettempruntime() > 0){
int tepruntime = r;
if(TCB[k].gettempruntime()-r<=0){
tepruntime = TCB[k].gettempruntime();
TCB[k].setwaittime(start + tepruntime - TCB[k].getruntime());
}
printf("Thread: %-2d Start: %-3d Runtime:%-2d \n",TCB[k].gettid(), start,tepruntime);
start = start + tepruntime;
TCB[k].settempruntime(r) ;
}
}
for(int m=0;m<Thread_Num;m++)
{
waittime += TCB[m].getwaittime();
//printf("TCB[%d].getwaittime():%d\n",m+1,TCB[m].getwaittime());
}
avwait = waittime / (float)Thread_Num;
printf("Total waitting time : %f\n",waittime);
printf("Average waitting time : %f\n",avwait);
}
//Priority schedule function
void Priority()
{
for(int k=0 ;k<Thread_Num;k++)
{
TCB[k].setvisit(0);
}
cout<<"-----------Priority:"<<endl;
int i,j;
int start = 0;
float waittime = 0;
float avwait = 0;
for(i=1;i<Thread_Num;i++)
{
for(j=0;j<Thread_Num;j++){
if(TCB[j].getpriority()==i && TCB[j].getvisit()==0){
printf("Thread: %-2d Start: %-3d Runtime: %-2d\n",TCB[j].gettid(),start,TCB[j].getruntime());
waittime = waittime + (float)start;
start = start + TCB[j].getruntime();
TCB[j].setvisit(1);
}
}
}
avwait = waittime / (float)Thread_Num;
printf("Total waitting time : %f\n",waittime);
printf("Average waitting time : %f\n",avwait);
}
//Main thread execute function to create 20 children threads
void *Children(void*)
{
int ret[Thread_Num];
t_init();
pthread_t tid[Thread_Num];
pthread_mutex_init(&Device_mutex,NULL);
int i,j;
for(i=0;i<Thread_Num;i++)
{
int k =i+1;
ret[i] = pthread_create(&tid[i],NULL,&t_print, &k);
if(ret[i] == 0) {
sleep(1);
}
else{
printf("Thread_%-2d failed!\n",i+1);
}
}
for(j=0;j<Thread_Num;j++)
pthread_join (tid[i], NULL);
pthread_mutex_destroy(&Device_mutex);
pthread_exit(0);
}
int main()
{
int ret1;
pthread_t tid1;//Declare main thread
ret1 = pthread_create(&tid1,NULL,&Children,NULL);//Create main thread
if(ret1 == 0)
{
printf("Main Thread ok!\n");
sleep(20);
}
else{
printf("Thread failed!\n");
}
FCFS();
SJF();
cout<<"Please enter RR time:\n";//Request RR time
int rr;
scanf("%d",&rr);
RR(rr);
Priority();
return 0;
}
OK!此程式碼的執行結果如下(部分):
第一張圖列印了一下虛擬PCB的部分內容:
第二張圖片列印了FCFS排程演算法執行結果:
第三張圖片列印了SJF排程演算法執行結果:
第四張圖片列印了RR排程演算法執行結果(部分):
第五張圖片列印了Priority排程演算法執行結果:
注意看每張圖下面的兩行資料,分別是不同演算法對應的總的程式的等待時間以及平均等待時間的大小,印證了SJF演算法通常是最少平均等待時間的排程演算法
最後希望大家能夠積極提建議,指出紕漏!
相關文章
- LInux實驗 : 程式排程模擬Linux
- linux程式排程Linux
- Go 併發程式設計 - runtime 協程排程(三)Go程式設計
- 模擬退火演算法Python程式設計(4)旅行商問題演算法Python程式設計
- 2. Go併發程式設計--GMP排程Go程式設計
- 作業系統精髓設計原理 程式排程作業系統
- linux中設定程式排程的優先順序別Linux
- 程式排程的原理和演算法探析演算法
- 程式排程演算法之先到先服務演算法
- Linux程式排程邏輯與原始碼分析Linux原始碼
- 模擬退火演算法Python程式設計(3)整數規劃問題演算法Python程式設計
- 一個51程式設計和模擬——流水燈程式設計
- 我猜,每個程式設計師對著電梯都想過排程演算法吧!程式設計師演算法
- 模擬退火演算法Python程式設計(2)約束條件的處理演算法Python程式設計
- Linux核心學習筆記(5)– 程式排程概述Linux筆記
- 【Go併發程式設計】第一篇 – Goroutines排程Go程式設計
- 【Go併發程式設計】第一篇 - Goroutines排程Go程式設計
- linux之 修改磁碟排程演算法Linux演算法
- COST231-WI模型通道模擬,原始碼模擬matlab程式設計原始碼模型原始碼Matlab程式設計
- Linux jpeg程式設計Linux程式設計
- Linux Bash程式設計Linux程式設計
- Proteus實現簡單51程式的設計與模擬
- 作業系統課程設計——處理機和程式排程演算法及記憶體分配回收機制作業系統演算法記憶體
- 基於Select模型的通訊模擬--win32程式設計程式碼模型Win32程式設計
- 【Linux】 Linux網路程式設計Linux程式設計
- Linux中什麼情況下會發生程式排程?Linux
- 增補部落格 第十七篇 python 模擬頁面排程LRU演算法Python演算法
- 天才模擬器程式設計師死於網路暴力中程式設計師
- python——asyncio模組實現協程、非同步程式設計(三)Python非同步程式設計
- windows核心程式設計--纖程Windows程式設計
- (整合)Linux下的多程式程式設計Linux程式設計
- Linux串列埠程式設計Linux串列埠程式設計
- Linux之shell程式設計Linux程式設計
- Linux Shell程式設計(1)Linux程式設計
- Linux Shell程式設計(2)Linux程式設計
- 排程系統設計精要
- 嵌入式軟體開發之程式架構設計-任務排程架構
- 四. 文字程式設計--Windows程式設計課程學習筆記程式設計Windows筆記
- JS模組化程式設計JS程式設計