進程控制模擬程序

實驗目的:

1 理解操作系統內核與應用程序的差別,哪些信號和操作是操作系統內核能捕捉到而應用程序無法捕捉到的?可以用什麼樣的操作去代替?

2 理解操作系統如何完成進程的控制(創建、撤消、阻塞、喚醒)

3 理解操作系統是如何利用進程控制塊來管理和控制進程的?

程序功能:

1 提供觸發進程創建、撤銷、阻塞、喚醒的界面和操作

2 完成進程的創建、撤銷、阻塞、喚醒功能

3 界面能在每次操作後分別顯示當前處於就緒態、阻塞態、運行態進程的狀態、優先權、進程id

4 實現進程調度的模擬,用基於優先權的調度算法實現進程調度。

程序功能實現:

        通過界面選項選擇進程創建、撤銷、阻塞、喚醒操作。

        就緒隊列,阻塞隊列、運行隊列通過全局變量的結構體指針實現。

        創建函數通過全局變量分配唯一進程ID,進程需要運行時間,優先級手動輸入。時間片大小默認爲5。


#include <stdio.h>
#include <stdlib.h>
#include<windows.h>

/*進程控制塊結構體*/
struct task_struct
{
    int id; //進程id
    int state; //-1就緒, 0運行, >0 阻塞(本程序默認爲1,不區分阻塞隊列)
    int priority;   //優先級
    int needtime;  //運行完畢所需時間
    int arrivedtime;    //已運行時間
    int slicetime;      //時間片剩餘時間,初始化爲5
    struct task_struct* next;
};

/*進程隊列*/
struct task_struct* runnableTask;   //運行
struct task_struct* unrunnableTask; //就緒
struct task_struct* stoppedTask;    //阻塞

//進程id控制,每次自增1
int id = 1;

/*函數名聲明*/
void taskController();
void createTask();
void stopTask();
void awakeTask();
void runTask();
void showTask();
void scheduleTask();
void getBigPriorityTask();
void deleteTask();

int main()
{
    runnableTask = NULL;
    unrunnableTask = NULL;
    stoppedTask = NULL;
    printf("進程模擬\n");
    while(1)
    {
        taskController();
    }
    return 0;
}

/*
本函數模擬進程控制程序
本函數執行一次運行,當前執行進程時間片減一
本函數創建進程不佔當前執行進程時間
*/

void taskController()
{
    char select;
    printf("本函數爲進程控制函數\n");
    printf("    1.創建進程\n");
    printf("    2.阻塞當前進程\n");
    printf("    3.喚醒選定進程\n");
    printf("    4.撤銷進程\n");
    printf("    5.無操作\n");
    printf("    6.退出\n");
    printf("\n請輸入你的選擇(1--6):");
    do
    {
        select=getchar();
    }
    while(select!='1'&&select!='2'&&select!='3'&&select!='4' &&select!='5' &&select!='6');
    switch(select)
    {
    case '1':
        createTask();
        break;
    case '2':
        stopTask();
        break;
    case '3':
        awakeTask();
        break;
    case '4':
        deleteTask();
        break;
    case '5':
        break;
    case '6':
        exit(0);
        break;
    default:
        return ;
    }
    runTask();
    showTask();
}

/*
創建進程,新創建進程添加到就緒進程隊尾
*/
void   createTask()
{
    printf("\n\n\n\n創建進程開始\n");
    if(unrunnableTask == NULL)  //判斷是否已有就緒進程 //判斷是否爲首指針
    {
        unrunnableTask = malloc(sizeof(struct task_struct));
        unrunnableTask->id = id++;
        printf("進程優先級:\n");
        scanf("%d",&unrunnableTask->priority);
        printf("進程運行需要的時間:\n");
        scanf("%d",&unrunnableTask->needtime);
        unrunnableTask->arrivedtime=0;
        unrunnableTask->state=-1;
        unrunnableTask->slicetime=0;
        unrunnableTask->next = NULL;
    }
    else
    {
        struct task_struct* test = unrunnableTask;
        while(test->next != NULL)
        {
            test = test->next;
        }
        test->next = malloc(sizeof(struct task_struct));
        test->next->id = id++;
        printf("進程優先級:\n");
        scanf("%d",&test->next->priority);
        printf("進程運行需要的時間:\n");
        scanf("%d",&test->next->needtime);
        test->next->arrivedtime=0;
        test->next->state=-1;
        test->next->next = NULL;
        test->next->slicetime=0;
        test = test->next;
    }
}

/*
撤銷內存程序
*/
void deleteTask()
{
    //撤銷運行進程
    char select;
    printf("撤銷運行進程輸入Y/y,不撤銷輸入N/n。\n");
    do
    {
        select=getchar();
    }
    while(select!='y'&&select!='n'&&select!='Y'&&select!='N');
    if(select=='y' || select=='Y')//進行撤銷
    {
        free(runnableTask);
        runnableTask = NULL;
        scheduleTask();
        return ;
    }
    //撤銷阻塞進程
    printf("撤銷阻塞進程輸入Y/y,不撤銷輸入N/n。\n");
    do
    {
        select=getchar();
    }
    while(select!='y'&&select!='n'&&select!='Y'&&select!='N');
    if(select=='y' || select=='Y')//選擇撤銷
    {
        struct task_struct* test = stoppedTask;
        while(test != NULL) //循環輸出阻塞進程信息
        {
            printf("本進程信息爲\n");
            printf("\n   進程名    優先級  需要時間    已用時間  剩餘時間片 進程狀態 \n");
            printf("%8d %8d %8d %10d %10d %10d \n",test->id,test->priority,test->needtime,test->arrivedtime, test->slicetime, test->state);
            printf("撤銷本進程輸入Y/y,不撤銷輸入N/n。\n");
            do
            {
                select=getchar();
            }
            while(select!='y'&&select!='n'&&select!='Y'&&select!='N');
            if(select=='y' || select=='Y')  //選擇撤銷該進程
            {
                //從進程隊列刪除撤銷進程
                if(stoppedTask == test)     //判斷是否爲隊首
                {
                    stoppedTask=test->next;
                }
                else    //撤銷進程非隊首
                {
                    struct task_struct* test3 = stoppedTask;
                    while(test3->next != test)
                    {
                        test3 = test3->next;
                    }
                    test3->next = test->next;
                }
                free(test);
                scheduleTask();
                return ;
            }
        }
    }
    //撤銷就緒進程
    printf("撤銷就緒進程輸入Y/y,不撤銷輸入N/n。\n");
    do
    {
        select=getchar();
    }
    while(select!='y'&&select!='n'&&select!='Y'&&select!='N');
    if(select=='y' || select=='Y')//選擇撤銷
    {
        struct task_struct* test = unrunnableTask;
        while(test != NULL) //循環輸出阻塞進程信息
        {
            printf("本進程信息爲\n");
            printf("\n   進程名    優先級  需要時間    已用時間  剩餘時間片 進程狀態 \n");
            printf("%8d %8d %8d %10d %10d %10d \n",test->id,test->priority,test->needtime,test->arrivedtime, test->slicetime, test->state);
            printf("撤銷本進程輸入Y/y,不撤銷輸入N/n。\n");
            do
            {
                select=getchar();
            }
            while(select!='y'&&select!='n'&&select!='Y'&&select!='N');
            if(select=='y' || select=='Y')  //選擇撤銷該進程
            {
                //從進程隊列刪除撤銷進程
                if(unrunnableTask == test)     //判斷是否爲隊首
                {
                    unrunnableTask=test->next;
                }
                else    //撤銷進程非隊首
                {
                    struct task_struct* test2 = unrunnableTask;
                    while(test2->next != test)
                    {
                        test2 = test2->next;
                    }
                    test2->next = test->next;
                }
                free(test);
                scheduleTask();
                return ;
            }
        }
    }

}

/*
阻塞進程程序
*/
void stopTask()
{
    if(runnableTask == NULL)
    {
        printf("無運行進程!\n");
        return ;
    }
    runnableTask->state = 1;    //阻塞進程狀態默認爲1,將進程放入阻塞隊列由runTask實現
}

/*
喚醒程序,喚醒優先級最大的進程,若有優先級相同進程,喚醒先進入隊列的進程
*/
void awakeTask()
{
    //無阻塞進程,退出
    if(stoppedTask == NULL)
    {
        printf("無阻塞進程!\n");
        return ;
    }
    int max = -100;
    struct task_struct* test = stoppedTask;
    while(test != NULL)
    {
        if(max < test->priority)
        {
            max = test->priority;
        }
        test = test->next;
    }
    if(max == stoppedTask->priority)     //判斷是否爲隊首
    {
        //將進程放入就緒隊列中
        if(unrunnableTask == NULL)//判斷就緒隊列是否爲空
        {
            unrunnableTask = stoppedTask;
            unrunnableTask->state=0;
            stoppedTask = stoppedTask->next;
            unrunnableTask->next = NULL;
        }
        else//放到就緒隊列隊尾
        {
            struct task_struct* test2 = unrunnableTask;
            while(test2->next != NULL)
            {
                test2 = test2->next;
            }
            stoppedTask = stoppedTask->next;
            test2->next = stoppedTask;
            test2->next->state=-1;
            test2->next->next=NULL;
        }
    }
    else        //喚醒進程不在隊首
    {
        //確定應喚醒進程在阻塞進程隊列的位置
        struct task_struct* test3 = stoppedTask;
        while(test3->next->priority != max)
        {
            test3 = test3->next;
        }
        //將進程放入就緒隊列中
        if(unrunnableTask == NULL)  //判斷就緒隊列是否爲空
        {
            unrunnableTask = test3->next;
            unrunnableTask->state=-1;
            test3->next = test3->next->next;
            unrunnableTask->next=NULL;
        }
        else        //放到就緒隊列隊尾
        {
            printf("test3");
            struct task_struct* test2 = unrunnableTask;
            while(test2->next != NULL)
            {
                test2 = test2->next;
            }
            test2->next = test3->next;
            test2->next->state=-1;
            test3->next = test3->next->next;
            test2->next->next=NULL;
        }
    }
    scheduleTask();
}

/*
模擬運行運行狀態進程
運行進程時間片時間減1
已用時間加1
判斷是否啓動進程調度程序
*/
void runTask()
{
    printf("\n\n\n\n運行進程開始\n");
    if(runnableTask != NULL)
    {
        printf("進程運行中……\n");
        runnableTask->arrivedtime += 1;
        runnableTask->slicetime -= 1;
        if(runnableTask->arrivedtime == runnableTask->needtime) //當運行進程完成
        {
            printf("當前運行進程執行完畢\n");
            printToScreen(runnableTask);
            printf("運行進程執行完畢,執行進程調度程序\n");
            free(runnableTask);
            runnableTask = NULL;
            scheduleTask();
        }
        else if(runnableTask->slicetime == 0)    //當運行進程時間片用完
        {
            //改變進程優先級,運行進程優先級-1,阻塞進程優先級+2
            runnableTask->priority -= 1;
            //將運行完進程放回就緒進程
            if(unrunnableTask == NULL)
            {
                unrunnableTask = runnableTask;
                unrunnableTask->state=-1;
            }
            else
            {
                struct task_struct* test = unrunnableTask;
                test->priority += 2;
                while(test->next != NULL)
                {
                    test = test->next;
                    test->priority += 2;
                }
                test->next = runnableTask;
                test->next->state = -1;
                test->next->next=NULL;
            }
            runnableTask = NULL;
            printf("運行進程時間片用完,執行進程調度程序\n");
            scheduleTask();
        }
        else if(runnableTask->state > 0)    //當運行進程被阻塞
        {
            //將被阻塞進程放入阻塞進程
            if(stoppedTask == NULL)
            {
                stoppedTask = runnableTask;
                stoppedTask->state=1;
                stoppedTask->next=NULL;
            }
            else
            {
                struct task_struct* test = stoppedTask;
                while(test->next != NULL)
                {
                    test = test->next;
                }
                test->next = runnableTask;
                test->next->state=1;
                test->next->next=NULL;
            }
            runnableTask = NULL;
            printf("運行進程被阻塞,執行進程調度程序\n");
            scheduleTask();
        }
    }
    else
    {
        printf("無正在運行進程,調用進程調度程序\n");
        scheduleTask();
    }
}

/*
模擬進程調度程序
*/
void scheduleTask()
{
    if(runnableTask==NULL||runnableTask->slicetime==0||runnableTask->needtime==runnableTask->arrivedtime||runnableTask->state>0)    //判斷是否符合切換運行進程條件
    {
        printf("\n\n\n\n運行調度開始\n");
        if(unrunnableTask != NULL)  //判斷有無就緒進程
        {
            if(runnableTask==NULL||runnableTask->slicetime==0||runnableTask->needtime==runnableTask->arrivedtime||runnableTask->state>0)
            {
                getBigPriorityTask();
            }
            else //運行進程隊列不需切換進程但進入
            {
                printf("進程調度程序出現未知錯誤\n");
            }
        }
        else //無就緒進程
        {
            printf("無就緒進程可供調度\n");
        }
    }
    else
    {
        printf("進入進程調度程序錯誤\n");
    }
}

/*
對進程排序,並將最大優先級的進程給運行進程
*/
void getBigPriorityTask()
{
    int max = -100;
    struct task_struct* test = unrunnableTask;
    while(test != NULL)
    {
        if(max < test->priority)
        {
            max = test->priority;
        }
        test = test->next;
    }
    if(max == unrunnableTask->priority)     //判斷是否爲隊首
    {
        runnableTask = unrunnableTask;
        runnableTask->state=0;
        unrunnableTask = unrunnableTask->next;
        runnableTask->next = NULL;
        runnableTask->slicetime=5;
    }
    else
    {
        test = unrunnableTask;
        while(test->next != NULL)
        {
            if(test->next->priority == max)
            {
                runnableTask=test->next;
                runnableTask->state=0;
                test->next = test->next->next;
                runnableTask->next = NULL;
                runnableTask->slicetime=5;
            }
            break;
        }
    }
}

/*
顯示進程狀態
*/
void showTask()
{
    printf("----------運行進程----------\n");
    if(runnableTask != NULL)
    {
        printToScreen(runnableTask);
    }
    printf("----------就緒進程----------\n");
    if(unrunnableTask != NULL)
    {
        printToScreen(unrunnableTask);
    }
    printf("----------阻塞進程----------\n");
    if(stoppedTask != NULL)
    {
        printToScreen(stoppedTask);
    }
}

/*
向屏幕輸出進程狀態
*/
void printToScreen(struct task_struct* test)
{
    printf("\n   進程名    優先級  需要時間    已用時間  剩餘時間片 進程狀態 \n");
    while(test != NULL)
    {
        printf("%8d %8d %8d %10d %10d %10d \n",test->id,test->priority,test->needtime,test->arrivedtime, test->slicetime, test->state);
        test = test->next;
    }
}


發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章