- 相關(guān)推薦
操作系統(tǒng)實驗二:進程管理
篇一:操作系統(tǒng)實驗報告 實驗一 進程管理
一、目的
進程調(diào)度是處理機管理的核心內(nèi)容。本實驗要求編寫和調(diào)試一個簡單的進程調(diào)度程序。通過本實驗加深理解有關(guān)進程控制塊、進程隊列的概念,并體會和了解進程調(diào)度算法的具體實施辦法。
二、實驗內(nèi)容及要求
1、設(shè)計進程控制塊PCB的結(jié)構(gòu)(PCB結(jié)構(gòu)通常包括以下信息:進程名(進程ID)、進程優(yōu)先數(shù)、輪轉(zhuǎn)時間片、進程所占用的CPU時間、進程的狀態(tài)、當前隊列指針等?筛鶕(jù)實驗的不同,PCB結(jié)構(gòu)的內(nèi)容可以作適當?shù)脑鰟h)。為了便于處理,程序中的某進程運行時間以時間片為單位計算。各進程的輪轉(zhuǎn)時間數(shù)以及進程需運行的時間片數(shù)的初始值均由用戶給定。
2、系統(tǒng)資源(r1…rw),共有w類,每類數(shù)目為r1…rw。隨 機產(chǎn)生n進程Pi(id,s(j,k)t),0<=i<=n,0<=j<=m,0<=k<=dt為總運行時間,在運行過程中,會隨機申請新的資源。
3、每個進程可有三個狀態(tài)(即就緒狀態(tài)W、運行狀態(tài)R、等待或阻塞狀態(tài)B),并假設(shè)初始狀態(tài)為就緒狀態(tài)。建立進程就緒隊列。
4、編制進程調(diào)度算法:時間片輪轉(zhuǎn)調(diào)度算法
本程序用該算法對n個進程進行調(diào)度,進程每執(zhí)行一次,CPU時間片數(shù)加1,進程還需要的時間片數(shù)減1。在調(diào)度算法中,采用固定時間片(即:每執(zhí)行一次進程,該進程的執(zhí)行時間片數(shù)為已執(zhí)行了1個單位),這時,CPU時間片數(shù)加1,進程還需要的時間片數(shù)減1,并排列到就緒隊列的尾上。
三、實驗環(huán)境
操作系統(tǒng)環(huán)境:Windows系統(tǒng)。
編程語言:C#。
四、實驗思路和設(shè)計
1、程序流程圖
2、主要程序代碼
//PCB結(jié)構(gòu)體
struct pcb
{
public int id; //進程ID
public int ra; //所需資源A的數(shù)量
public int rb; //所需資源B的數(shù)量
public int rc; //所需資源C的數(shù)量
public int ntime; //所需的時間片個數(shù)
public int rtime; //已經(jīng)運行的時間片個數(shù)
public char state; //進程狀態(tài),W(等待)、R(運行)、B(阻塞)
//public int next;
}
ArrayList hready = new ArrayList();
ArrayList hblock = new ArrayList();
Random random = new Random();
//ArrayList p = new ArrayList();
int m, n, r, a,a1, b,b1, c,c1, h = 0, i = 1, time1Inteval;//m為要模擬的進程個數(shù),n為初始化進程個數(shù)
//r為可隨機產(chǎn)生的進程數(shù)(r=m-n)
//a,b,c分別為A,B,C三類資源的總量
//i為進城計數(shù),i=1…n
//h為運行的時間片次數(shù),time1Inteval為時間片大。ê撩耄
//對進程進行初始化,建立就緒數(shù)組、阻塞數(shù)組。
public void input()//對進程進行初始化,建立就緒隊列、阻塞隊列
{
m = int.Parse(textBox4.Text);
n = int.Parse(textBox5.Text);
a = int.Parse(textBox6.Text);
b = int.Parse(textBox7.Text);
c = int.Parse(textBox8.Text);
a1 = a;
b1 = b;
c1 = c;
r = m - n;
time1Inteval = int.Parse(textBox9.Text);
timer1.Interval = time1Inteval;
for (i = 1; i <= n; i++)
{
pcb jincheng = new pcb();
jincheng.id = i;
jincheng.ra = (random.Next(a) + 1);
jincheng.rb = (random.Next(b) + 1);
jincheng.rc = (random.Next(c) + 1);
jincheng.ntime = (random.Next(1, 5));
jincheng.rtime = 0;
listBox1.Items.Add("產(chǎn)生進程ID:" + jincheng.id);
listBox1.Items.Add("所需A資源數(shù)目:" + jincheng.ra);
listBox1.Items.Add("所需B資源數(shù)目:" + jincheng.rb);
listBox1.Items.Add("所需C資源數(shù)目:" + jincheng.rc);
listBox1.Items.Add("所需時間片數(shù):" + jincheng.ntime);
if ((a - jincheng.ra) >= 0 && (b - jincheng.rb) >= 0 && (c - jincheng.rc) >= 0)
{
a = a - jincheng.ra;
b = b - jincheng.rb;
c = c - jincheng.rc;
jincheng.state = 'W';
hready.Add(jincheng);//加入就緒隊列
}
else
{
jincheng.state = 'B';
hblock.Add(jincheng);//加入阻塞隊列
}
listBox1.Items.Add("當前進程狀態(tài):" + jincheng.state);
}
}
//從數(shù)組起始地址開始輸出該數(shù)組的內(nèi)容
public void disp(ArrayList list)
{
ArrayList list1 = new ArrayList();
list1 = list;
if (list1.Count > 0)
{
for (int j = 0; j < list1.Count; j++)
{
pcb p = (pcb)list1[j];
listBox1.Items.Add(" " + p.id.ToString() + " " + p.state.ToString() + "
p.ra.ToString() + "" + p.rb.ToString() + "" + p.rc.ToString()+"
p.ntime.ToString() + " " + p.rtime.ToString() + " ");
}
}
else
{
listBox1.Items.Add(" 該隊列中沒有進程! ");
}
}
//輸出就緒數(shù)組和阻塞數(shù)組的信息
public void outputall()
{
listBox1.Items.Add(" =======CPU運行了:" + h.ToString() + "次======= ");
listBox1.Items.Add("*********當前就緒隊列的信息!*********");
listBox1.Items.Add("進程ID 進程狀態(tài) A資源數(shù) B資源數(shù) C資源數(shù) 所需時間片 已運行時間片");
disp(hready);
listBox1.Items.Add("*********當前就阻塞列的信息!*********");
listBox1.Items.Add("進程ID 進程狀態(tài) A資源數(shù) B資源數(shù) C資源 所需時間片 已運行時間片");
disp(hblock);
}
//運行就緒數(shù)組的頭進程,運行一個時間片,輪轉(zhuǎn)一個時間片,時間片輪轉(zhuǎn)調(diào)度算法
public void running()
{
ArrayList hready1 = new ArrayList();
hready1 = hready;
pcb p1 = new pcb();
p1=(pcb)hready1[0];
p1.state='R';
p1.rtime= p1.rtime + 1;
h=h+1;
listBox1.Items.Add(" ~~~~~~~當前正在運行進程ID是:" +p1.id + "~~~~~~~~ ");
listBox1.Items.Add(" 進程ID 進程狀態(tài) A資源數(shù) B資源數(shù) C資源數(shù) 所需時間片 已運行時間片 ");
listBox1.Items.Add(p1.id + " " +p1.state+ "" + p1.ra + " " + p1.rb + "" + p1.rc + "" + p1.ntime + "" + p1.rtime);
if (p1.ntime==p1.rtime)
{
listBox1.Items.Add(p1.id.ToString()+"的進程已經(jīng)完成! ");
a = a + p1.ra;
b = b + p1.rb;
c = c + p1.rc;
hready.RemoveAt(0);
}
else
{
p1.state='W';
hready1.Add(p1);
hready.RemoveAt(0);
}
}
//檢測當前資源數(shù)目是否滿足阻塞數(shù)組里進程的需求
public void testblock()
{
ArrayList hblock1 = new ArrayList();
hblock1 = hblock;
for (int m = 0; m < hblock1.Count; m++)
{
pcb p1 = new pcb();
篇二:操作系統(tǒng)進程管理實驗
一、實驗?zāi)康?/p>
通過編寫進程管理的算法,要求學生掌握整個進程管理的各個環(huán)節(jié),進程的數(shù)據(jù)結(jié)構(gòu)描述,進程的各種狀態(tài)之間的轉(zhuǎn)換,以及進程的調(diào)度算法。以加深對進程的概念及進程調(diào)度算法的理解,并且提高鏈表的應(yīng)用能力,達到提高編程能力的目的。
二、實驗原理及基本技術(shù)路線圖(方框原理圖)
用C語言或C++語言開發(fā)。需要定義PCB的數(shù)據(jù)結(jié)構(gòu),用鏈表的形式管理進程,采用多級反饋隊列調(diào)度的算法模擬進程的控制。要求有創(chuàng)建、撤銷、調(diào)度、阻塞、喚醒進程等功能。
①進程的狀態(tài)轉(zhuǎn)換圖
、跀(shù)據(jù)結(jié)構(gòu)定義、主要變量的說明、函數(shù)的說明及各原語的功能說明
typedef struct PCB 定義結(jié)構(gòu)體PCB進程控制塊;char NAME[20] 定義結(jié)構(gòu)體變量,進程名;long
ID 定義進程id;int RUNTIME 定義進程運行時間;char STATE[6] 定義進程狀態(tài) 有 ready 、wait 、run;
int PRIORITY定義權(quán)值。 typedef struct QNode { PCB pcb; struct QNode *next; }QueuePtr; 定義單鏈表,有定義指針next。typedef struct LinkQueue { int prior; QueuePtr *front; QueuePtr *rear; int PartTime; }LinkQueue;
鏈隊列中定:優(yōu)先級、結(jié)構(gòu)體里的QueuePtr類型指針變量,指向該優(yōu)先級的進程的頭結(jié)點和尾結(jié)點,還運行的時間片。LinkQueue Readyqueue[10] 鏈隊列的單鏈表。
void schedule() 聲明調(diào)度函數(shù),用來調(diào)度進程的運行;void show() 聲明輸出函數(shù),用來輸出的一個函數(shù);void Create()聲明創(chuàng)建進程的函數(shù),用來創(chuàng)建進程。
yunxingshijian=1+(int)(rand()%30); 此語句是隨機生成一個整數(shù)賦給運行時間RUNTIME;
youxianji=1+(int)(rand()%9); 該語句隨機生成一個整數(shù)(1~9)賦給優(yōu)先級; strcpy(p->pcb.NAME,name)將名字賦給PCB塊;strcpy(p->pcb.STATE,"Ready")將進程狀態(tài)賦給PCB塊; p->pcb.PRIORITY=youxianji將優(yōu)先級賦給PCB塊; p->pcb.RUNTIME=yunxingshijian; 將運行時間賦給PCB塊; p->pcb.ID=id 將id號賦給PCB塊。
{Readyqueue[i].front->next=p->next; Readyqueue[i+1].rear->next=p; Readyqueue[i+1].rear=p;p->next=NULL; } p移到下一隊列的隊尾,使Readyqueue[i+1].rear指向最后一個結(jié)點。{Readyqueue[i].front->next=p->next; Readyqueue[9].rear->next=p; p->next=NULL; Readyqueue[9].rear=p; } //p->next前移,把p移到運行結(jié)束的隊列Readyqueue[9].rear。
、鄱嗉壏答侁犃姓{(diào)度算法的描述
一個進程被調(diào)度,則其運行時間有p->pcb.RUNTIME=p->pcb.RUNTIME-(int )pow(2,i+1),此后如果該進程的p->pcb.RUNTIME<0或p->pcb.RUNTIME=0,此進程就結(jié)束且加入到Readyqueue[9].rear->next=p且p->next=NULL。沒有結(jié)束就移加到下一隊列的尾部且優(yōu)先級減“1”(Readyqueue[i].front->next=p->next;Readyqueue[i+1].rear->next=p;Readyqueue[i+1].rear=p;p->next=NULL; )。然后往下執(zhí)行。如此循環(huán).iv Readyqueue[i].front->next!=NULL發(fā)生時,就往下一優(yōu)先級運行。直到所有進程結(jié)束。
、艹绦蚬δ芙Y(jié)構(gòu)圖、流程圖
<1>創(chuàng)建進程函數(shù)Create()
三、所用儀器、材料(設(shè)備名稱、型號、規(guī)格等)。
所用儀器:計算中心201;操作系統(tǒng):Microsoft Visual C++;軟件平臺:Microsoft Visual C++
四、實驗方法、步驟
#include#include#include#include#include
typedef struct PCB //定義結(jié)構(gòu)體PCB進程控制塊 {
typedef struct QNode//單鏈表 {
PCB pcb;
typedef struct LinkQueue//鏈隊列
{
int prior; //優(yōu)先級
LinkQueue Readyqueue[10]; //鏈隊列的單鏈表
int N; //N為當前進程數(shù)
void schedule();//聲明調(diào)度函數(shù)
void show(); //聲明輸出函數(shù)
void InitQueue() //隊列的初始化、給每個隊列加個頭結(jié)點 {
for(int i=0;i<10;i++) {
Readyqueue[i].PartTime=(int )pow(2,i+1); //每個進程的時間片
Readyqueue[i].prior=9-i;//每進程的優(yōu)先級
Readyqueue[i].front=(QueuePtr*)malloc(sizeof(QueuePtr)); //為進程申請空間
QueuePtr *front; //結(jié)構(gòu)體里的QueuePtr類型指針變量,指向該優(yōu)先級的進程的頭結(jié)點
QueuePtr *rear; //結(jié)構(gòu)體里的QueuePtr類型指針變量,指向該優(yōu)先級的進程的尾結(jié)點
int PartTime; //時間片
struct QNode *next;
}
QueuePtr;
char NAME[20]; //結(jié)構(gòu)體變量,進程名
long ID; //進程id
int RUNTIME; //進程運行時間
char STATE[6]; //進程狀態(tài)
ready wait run int PRIORITY;//權(quán)值
}PCB;
}LinkQueue;
}
}
Readyqueue[i].rear=Readyqueue[i].front;//初始化單鏈的頭結(jié)點和尾結(jié)點指向同一位置 Readyqueue[i].front->next=NULL; //初始化時Readyqueue[i].front->next為空
//***************************創(chuàng)建進程**************************************************
void Create() {
InitQueue();
char name[20]; long id=201031101; //定義ID和初始化為201031101
QueuePtr *p;
int yunxingshijian,youxianji;//運行時間、優(yōu)先級
printf(" 請輸入要創(chuàng)建進程的數(shù)目:");
fflush(stdin);
scanf("%d",&m);
{
printf(" 輸入進程名:"); //用戶輸入用戶名
scanf("%s",&name);
int m;
for(int j=1;j<=m;j++) //創(chuàng)建用戶所需進程m個
srand((int)time(0));
yunxingshijian=1+(int)(rand()%30);//隨機生成一個整數(shù)賦給運行時間
printf(" 運行時間:%d",yunxingshijian);
srand((int)time(0));
for(int i=0;i<9;i++) //通過優(yōu)先級尋找該進程應(yīng)放置的隊列
{
if(youxianji==9-i)
{
k=Readyqueue[i].front; //k為移動指針,尋找隊列末尾進程
strcpy(p->pcb.NAME,name); //將名字賦給PCB塊
strcpy(p->pcb.STATE,"Ready");//將進程狀態(tài)賦給PCB塊
p->pcb.PRIORITY=youxianji;//將優(yōu)先級賦給PCB塊
p->pcb.RUNTIME=yunxingshijian; //將運行時間賦給PCB塊
p->pcb.ID=id; //將id號賦給PCB塊
youxianji=1+(int)(rand()%9);//隨機生成一個整數(shù)(1~9)賦給優(yōu)先級
printf(" 優(yōu)先級:%d",youxianji);
p=(QueuePtr *)malloc(sizeof(QueuePtr)); //插入就緒隊列
QueuePtr *k;
篇三:操作系統(tǒng)實驗二(進程管理)
實驗題目:
(1) 進程的創(chuàng)建編寫一段程序,使用系統(tǒng)調(diào)用fork( )創(chuàng)建兩個子進程。當此程序運行時,在系統(tǒng)中有一個父進程和兩個子進程活動。讓每一個進程在屏幕上顯示一個字符:父進程顯示字符“a”;子進程分別顯示字符“b”和字符“c”。試觀察記錄屏幕上的顯示結(jié)果,并分析原因。
。2) 進程的控制修改已編寫的程序,將每個進程輸出一個字符改為每個進程輸出一句話,在觀察程序執(zhí)行時屏幕上出現(xiàn)的現(xiàn)象,并分析原因。
(3) 編制一段程序,使其實現(xiàn)進程的軟中斷通信。要求:使用系統(tǒng)調(diào)用fork( )創(chuàng)建兩個子進程,再用系統(tǒng)調(diào)用signal( )讓父進程捕捉鍵盤上來的中斷信號(即按Del鍵);當捕捉到中斷信號后,父進程調(diào)用系統(tǒng)調(diào)用kill( )向兩個子進程發(fā)出信號,子進程捕捉到信號后分別輸出下列信息后終止:Child process 1 is killed by parent!Child process 2 is killed by parent! 父進程等待兩個子進程終止后,輸出如下的信息后終止:Parent process is killed! 在上面的程序中增加語句signal(SIGINT, SIG_IGN)和 signal(SIGQUIT, SIG_IGN),觀察執(zhí)行結(jié)果,并分析原因。
。4) 進程的管道通信編制一段程序,實現(xiàn)進程的管道通信。使用系統(tǒng)調(diào)用pipe( )建立一條管道線;兩個進程P1和P2分別向管道各寫一句話: Child 1 is sending a message! Child 2 is sending a message! 而父進程則從管道中讀出來自于兩個子進程的信息,顯示在屏幕上。要求父進程先接收子進程P1發(fā)來的消息,然后再接收子進程P2發(fā)來的消息。
實驗源程序及報告:
。1)、進程的創(chuàng)建
#include
int main(int argc, char *argv[])
{
int pid1,pid2; /*fork first child process*/
if ( ( pid1=fork() ) < 0 )
{
printf( "ProcessCreate Failed!");
exit(-1);
}
if ( ( pid1=fork() ) == 0 )
{
printf( "b " );
}
/*fork second child process*/
if ( ( pid2=fork() ) < 0 )
{
printf( "ProcessCreate Failed!");
exit(-1);
}
if ( ( pid2=fork() ) == 0 )
{
printf( "c " );
}
/*parent process*/
else
{
wait(NULL);
printf( "a " );
exit(0);
}
return 0;
}
。2)、進程的控制
#include
int main(int argc, char *argv[])
{int pid1,pid2;
/*fork first child process*/
if ( ( pid1=fork() ) < 0 )
{
printf( "ProcessCreate Failed!");
exit(-1);
}
if ( ( pid1=fork() ) == 0 )
{
printf( "This is my Unix OS program! " );
}
/*fork second child process*/
if ( ( pid2=fork() ) < 0 )
{
printf( "ProcessCreate Failed!");
exit(-1);
}
if ( ( pid2=fork() ) == 0 )
{
printf( "This is the second Child process! " );
}
/*parent process*/
else
{
wait(NULL);
printf( "This is the Parent process " );
exit(0);
}
return 0;
}
(3) 編制一段程序,使其實現(xiàn)進程的軟中斷通信。
#include
#include
#include
#include
int wait_flag; void stop( );
main( )
{
int pid1, pid2;signal(3, stop);
while ((pid1 = fork( )) == -1);
if ( (pid1 = fork() ) > 0)
{
while ((pid2 = fork( )) == -1);
if (( pid2 = fork()) > 0 )
{
}
else
{
} wait_flag = 1;
signal(SIGINT, stop);
sleep(5);
kill(pid1, 16);
kill(pid2,17);
wait(0); wait(0);
printf(" Parent process is killed. ");
exit(0); wait_flag = 1;
signal(17, stop);
printf(" Child process 2 is killed by parent. ");
exit(0);
}
【 操作系統(tǒng)實驗二:進程管理】相關(guān)文章:
linux操作系統(tǒng)要查看系統(tǒng)進程的辦法07-24
Linux進程管理優(yōu)秀教程03-09
操作系統(tǒng)實驗心得體會05-13
Windows操作系統(tǒng)的管理的詳細解析07-22
六招管理你的操作系統(tǒng)詳解12-17