操作系统实验一——模拟进程调度时间片轮转算法

原创 2006年05月21日 13:50:00

本程序用于模拟进程。
总体思路为:用一个调度线程来模拟操作系统的调度进程,用一个线程来模拟一个进程。于是,对应于每一个被模拟的进程,都有相应的线程来模拟,并在调度线程的调度下,实现时间片轮转的调度算法。
具体实现:
PCB块的数据结构:
typedef struct PCB {
 int id;
 char name[20];
 int status;
 int ax, bx, cx, dx;
 int pc;
 int psw;
 struct PCB* next;
 HANDLE hThis;
 DWORD threadID;
 int count;
}PCB, *pPCB;

ReadyList 和 FreeList的数据结构:
typedef struct {
 pPCB head;
 pPCB tail;
 int pcbNum;
}readyList, freeList, *pList;

状态列表:
enum STATUS { RUN, READY, WAIT };

PCB块总数:
const int PCB_LIMIT = 10;

在本程序中,调度线程为DWORD WINAPI scheduleThread(LPVOID lpParameter)。模拟进程的线程为:DWORD WINAPI processThread(LPVOID lpParameter)。

程序中每个时间片设置为1秒,其中每个进程在每个时间片内可以运行两条指令,将导致其pc加2。每个进程的各个寄存器,在进程生成时自动生成。

程序可以动态的创建进程,动态的撤销进程,并将最终的运行结果写在process_log.txt文件中。程序的运行界面如下:(可直接运行文件夹可执行程序中的Pro_test。)
create pro_name pro_len(如create p0 10)用于创建一个新进程。
remove pro_name (如remove p0)用于撤销一个进程。
current 用于显示当前运行进程以及当前就绪队列信息。

源代码如下:

pcb.h
#ifndef PCB_H
#define PCB_H

typedef struct PCB {
 int id;
 char name[20];
 int status;
 int ax, bx, cx, dx;
 int pc;
 int psw;
 struct PCB* next;
 HANDLE hThis;
 DWORD threadID;
 int count;
}PCB, *pPCB;

typedef struct {
 pPCB head;
 pPCB tail;
 int pcbNum;
}readyList, freeList, *pList;

typedef struct apply{
 char name[20];
 int time;
 struct apply* next;
}applyProcess, *applyList;

typedef struct {
 applyList head;
 applyList tail;
 int applyNum;
}applyQueue;

enum STATUS { RUN, READY, WAIT };
const int PCB_LIMIT = 10;

void init();
void createProcess(char* name, int ax);
void addApplyProcess(char* name, int time);
void createIfAnyApply();
void scheduleProcess();
void removeProcess(char* name);
void fprintReadyList();
void printCurrent();

#endif


pcb.cpp

#include <stdio.h>
#include <stdlib.h>
#include <time.h>
#include <windows.h>
#include "pcb.h"
#include "funCode.h"

pList   pReadyList = new readyList;
pList   pFreeList = new freeList;
pPCB   runPCB;
bool   firstTime = true;
applyQueue*  queue = new applyQueue;
HANDLE   hSchedule = NULL;
bool   schIsActive = false;
CRITICAL_SECTION cs_ReadyList;
CRITICAL_SECTION cs_SaveSection;
//CRITICAL_SECTION cs_RunPCB;

extern FILE* log;
extern PC;
extern FUN functions[FUN_NUM];

void initialPCB(pPCB p) {
 p->id = 0;
 strcpy(p->name, "");
 p->status = WAIT;
 p->ax = 0;
 p->bx = 0;
 p->cx = 0;
 p->dx = 0;
 p->pc = 0;
 p->psw = 0;
 p->next = NULL;
 p->hThis = NULL;
 p->threadID = 0;
 p->count = 0;
}

pPCB getPcbFromFreeList() {
 pPCB freePCB = NULL;
 if (pFreeList->head != NULL && pFreeList->pcbNum > 0) {
  freePCB = pFreeList->head;
  pFreeList->head = pFreeList->head->next;
  pFreeList->pcbNum--;
 }
 return freePCB;
}

void returnPcbToFreeList(pPCB p) {
 initialPCB(p);

 if (pFreeList->head == NULL) {
  pFreeList->head = p;
  pFreeList->tail = p;
  pFreeList->pcbNum++;
 } else {
  pFreeList->tail->next = p;
  pFreeList->tail = p;
  pFreeList->pcbNum++;
 }
}

DWORD WINAPI processThread(LPVOID lpParameter) {
 pPCB currentPcb = (pPCB)lpParameter;
 MSG msg;

 while (true) {
  Sleep(500);
  fprintf(log, "process %d:%s is running.../n", currentPcb->id, currentPcb->name);
  currentPcb->pc++;
  fflush(log);

  EnterCriticalSection(&cs_SaveSection);
  if (PeekMessage(&msg, NULL, 0, 0,PM_REMOVE)) {
   if (msg.message == WM_USER) {
    //printf("Process %d:%s recieve a message. It's to be suspended./n",
    // currentPcb->id, currentPcb->name);
   }
  }
  LeaveCriticalSection(&cs_SaveSection);
 }
 /*
 while (true) {
  PC = currentPcb->pc;
  
  for (int i = 0; i < TIME_SLOT; i++) {
   (*functions[PC%FUN_NUM].pc)();
   PC++;
  }
  
  currentPcb->pc = PC;
  SuspendThread(currentPcb->hThis);
 }*/

 return 0;
}

DWORD WINAPI scheduleThread(LPVOID lpParameter) {
 pList readyList = (pList)lpParameter;
 while (true) {
  scheduleProcess();

  if (readyList->pcbNum <= 0 && schIsActive) {
   schIsActive = false;
   SuspendThread(hSchedule);
  } else if (readyList->pcbNum >0 && !schIsActive) {
   schIsActive = true;
   ResumeThread(hSchedule);
  }
 }

 return 0;
}

void init() {
 ////////////////////////////////////////////////////////////////
 if (firstTime) {
  pReadyList->head = NULL;
  pReadyList->tail = NULL;
  pReadyList->pcbNum = 0;

  pFreeList->head = NULL;
  pFreeList->tail = NULL;
  pFreeList->pcbNum = 0;

  for (int i = 0; i < PCB_LIMIT; i++) {
   pPCB pTempPCB = new PCB;
   initialPCB(pTempPCB);
   pTempPCB->id = i;
   if (pFreeList->head == NULL) {
    pFreeList->head = pTempPCB;
    pFreeList->tail = pTempPCB;
    pFreeList->pcbNum++;
   } else {
    pFreeList->tail->next = pTempPCB;
    pFreeList->tail = pTempPCB;
    pFreeList->pcbNum++;
   }
  }

  hSchedule = CreateThread(NULL, NULL, scheduleThread, pReadyList, CREATE_SUSPENDED, 0);

  InitializeCriticalSection(&cs_ReadyList);
  InitializeCriticalSection(&cs_SaveSection);
  //InitializeCriticalSection(&cs_RunPCB);

  firstTime = false;
 }
 //////////////////////////////////////////////////////////////////////
}

void createProcess(char* name, int count/*, int pc*/) { 
 //
 EnterCriticalSection(&cs_ReadyList);
 //
 if (pFreeList->pcbNum > 0) {
  pPCB newPcb = getPcbFromFreeList();
  newPcb->status = READY;
  strcpy(newPcb->name, name);
  newPcb->count = count;
  //newPcb->pc = 0;
  newPcb->next = NULL;

  srand( (unsigned)time( NULL ) );
  newPcb->ax = rand() % 20;
  newPcb->bx = rand() % 20;
  newPcb->cx = rand() % 20;
  newPcb->dx = rand() % 20;
  newPcb->pc = rand() % 20;
  newPcb->psw = rand() % 20;
  
  if (pReadyList->pcbNum == 0) {
   pReadyList->head = newPcb;
   pReadyList->tail = newPcb;
   pReadyList->pcbNum++;
  } else {
   pReadyList->tail->next = newPcb;
   pReadyList->tail = newPcb;
   pReadyList->pcbNum++;
  }
  
  fprintf(log, "New Process Created.  /nProcess ID: %d  Process Name: %s  Process Length: %d/n",
   newPcb->id, newPcb->name, newPcb->count);
  fprintf(log, "AX: %d/tBX: %d/tCX: %d/tDX: %d/tPC: %d/tPSW: %d/n/n",
   newPcb->ax, newPcb->bx, newPcb->cx, newPcb->dx, newPcb->pc, newPcb->psw);
  fprintf(log, "Current ReadyList is:/n");
  fprintReadyList();

  newPcb->hThis = CreateThread(NULL, NULL, processThread, newPcb, CREATE_SUSPENDED, &(newPcb->threadID));
 } else {
  printf("PCB used out/n");
  fprintf(log, "New process intend to append. But PCB has been used out!/n/n");
 }
 //
 LeaveCriticalSection(&cs_ReadyList);
 //
}

void scheduleProcess() {
 ////
 //EnterCriticalSection(&cs_RunPCB);
 ////
 
 //
 EnterCriticalSection(&cs_ReadyList);
 //
 if (pReadyList->pcbNum > 0) {
  runPCB = pReadyList->head;
  
  pReadyList->head = pReadyList->head->next;
  if (pReadyList->head == NULL) {
   pReadyList->tail = NULL;
  }
  pReadyList->pcbNum--;

  runPCB->count--;
  fprintf(log, "Process %d:%s is to be scheduled./n"
   "Process %d:%s Information:/tAX: %d/tBX: %d/tCX: %d/tDX: %d/tPC: %d/tPSW: %d/n/n",
   runPCB->id, runPCB->name, runPCB->id, runPCB->name,
   runPCB->ax, runPCB->bx, runPCB->cx, runPCB->dx, runPCB->pc, runPCB->psw);
  ResumeThread(runPCB->hThis);
  runPCB->status = RUN;
  Sleep(1000);
  fprintf(log, "/nOne time slot used out!/n/n");
  runPCB->status = READY;
  PostThreadMessage(runPCB->threadID, WM_USER, 0, 0);
  //
  EnterCriticalSection(&cs_SaveSection);
  //
  SuspendThread(runPCB->hThis);
  //
  LeaveCriticalSection(&cs_SaveSection);
  //

  if (runPCB->count <= 0 && runPCB != NULL) {
   printf("/nProcess %d:%s has finished./n", runPCB->id, runPCB->name);
   printf("COMMAND>");
   fprintf(log, "Process %d:%s has finished./n/n", runPCB->id, runPCB->name);
   fprintf(log, "Current ReadyList is:/n");
   fprintReadyList();
   fflush(log);

   TerminateThread(runPCB->hThis, 0);
   returnPcbToFreeList(runPCB);
   runPCB = NULL;
  }
  
  if (runPCB != NULL) {
   if (pReadyList->pcbNum == 0) {
    pReadyList->head = runPCB;
    pReadyList->tail = runPCB;
   } else {
    pReadyList->tail->next = runPCB;
    pReadyList->tail = runPCB;
   }
   runPCB->next = NULL;
   runPCB = NULL;
   pReadyList->pcbNum++;
  }
 } else if (pReadyList != NULL) {
  pReadyList->head = NULL;
  pReadyList->tail = NULL;
  pReadyList->pcbNum = 0;
 }
 //
 LeaveCriticalSection(&cs_ReadyList);
 //
 ////
 //LeaveCriticalSection(&cs_RunPCB);
 ////
}

void addApplyProcess(char* name, int time) {
 applyProcess* newApply = new applyProcess;
 strcpy(newApply->name, name);
 newApply->time = time;
 newApply->next = NULL;
 
 if (queue->applyNum <= 0) {
  queue->head = newApply;
  queue->tail = newApply;
  queue->applyNum = 1;
 } else {
  queue->tail->next = newApply;
  queue->tail = newApply;
  queue->applyNum++;
 }

 createIfAnyApply();
}

void createIfAnyApply() {
 if (queue != NULL && queue->applyNum >= 1) {
  applyProcess* temp = queue->head;
  createProcess(temp->name, temp->time);
  
  if (queue->applyNum <= 1) {
   queue->head = NULL;
   queue->tail = NULL;
  } else {
   queue->head = queue->head->next;
  }
  
  queue->applyNum--;
  delete temp;
 }

 if (!schIsActive) {
  schIsActive = true;
  ResumeThread(hSchedule);
 }
}

void removeProcess(char* name) {
 pPCB removeTarget = NULL;
 pPCB preTemp = NULL;

 //
 EnterCriticalSection(&cs_ReadyList);
 //
 if (runPCB != NULL && strcmp(name, runPCB->name) == 0) {
  removeTarget = runPCB;
  
  printf("Process %d:%s has been removed./n", removeTarget->id, removeTarget->name);
  fprintf(log, "/nProcess %d:%s has been removed./n", removeTarget->id, removeTarget->name);
  
  TerminateThread(removeTarget->hThis, 0);
  returnPcbToFreeList(removeTarget);
  runPCB = NULL;

  fprintf(log, "Current ReadyList is:/n");
  fprintReadyList();
  fflush(log);

  //
  LeaveCriticalSection(&cs_ReadyList);
  //
  return;
 } else if (pReadyList->head != NULL) {
  for (removeTarget = pReadyList->head, preTemp = pReadyList->head;
   removeTarget != NULL; removeTarget = removeTarget->next) {

   if (removeTarget == pReadyList->head && strcmp(name, removeTarget->name) == 0) {
    pReadyList->head = pReadyList->head->next;
    if (pReadyList->head == NULL) {     
     pReadyList->tail = NULL;
    }
    
    printf("Process %d:%s has been removed./n", removeTarget->id, removeTarget->name);
    fprintf(log, "/nProcess %d:%s has been removed./n", removeTarget->id, removeTarget->name);
    
    TerminateThread(removeTarget->hThis, 0);
    returnPcbToFreeList(removeTarget);
    pReadyList->pcbNum--;

    fprintf(log, "Current ReadyList is:/n");
    fprintReadyList();
    fflush(log);

    //
    LeaveCriticalSection(&cs_ReadyList);
    //
    return;
   } else if (removeTarget != pReadyList->head && strcmp(name, removeTarget->name) == 0) {
    preTemp->next = removeTarget->next;
    if (removeTarget == pReadyList->tail) {
     pReadyList->tail = preTemp;
    }
    
    printf("Process %d:%s has been removed./n", removeTarget->id, removeTarget->name);
    fprintf(log, "/nProcess %d:%s has been removed./n", removeTarget->id, removeTarget->name);
    
    TerminateThread(removeTarget->hThis, 0);
    returnPcbToFreeList(removeTarget);
    pReadyList->pcbNum--;

    fprintf(log, "Current ReadyList is:/n");
    fprintReadyList();
    fflush(log);

    //
    LeaveCriticalSection(&cs_ReadyList);
    //
    return;
   } else if (removeTarget != pReadyList->head) {
    preTemp = preTemp->next;
   }
  }
 }
 
 printf("Sorry, there's no process named %s/n", name);
 //
 LeaveCriticalSection(&cs_ReadyList);
 //
 return;
}

void fprintReadyList() {
 pPCB tmp = NULL;
 tmp = pReadyList->head;
 if (tmp != NULL) {
  for (int i = 0; i < pReadyList->pcbNum; i++) {
   fprintf(log, "--%d:%s--", tmp->id, tmp->name);
   tmp = tmp->next;
  }
 } else {
  fprintf(log, "NULL");
 }
 fprintf(log, "/n/n");
}

void printReadyList() {
 pPCB tmp = NULL;
 tmp = pReadyList->head;
 if (tmp != NULL) {
  for (int i = 0; i < pReadyList->pcbNum; i++) {
   printf("--%d:%s--", tmp->id, tmp->name);
   tmp = tmp->next;
  }
 } else {
  printf("NULL");
 }
 printf("/n/n");
}

void printCurrent() {
 if (runPCB != NULL) {
  printf("Process %s is running.../n", runPCB->name);
 } else {
  printf("No process is running./n");
 }
 printf("Current readyList is:/n");
 printReadyList();
}


main.cpp

#include <stdio.h>
#include <string.h>

#include <windows.h>

#include "pcb.h"
#include "funCode.h"

FILE *log;
int PC = 0;

extern applyQueue* queue;

void helpInfo() {
 printf("/n************************************************/n");
 printf("COMMAND LIST:/n");
 printf("create process_name process_length (create p0 8)/n"
  "/t append a process to the process list/n");
 printf("remove process_name (remove p0)/n"
  "/t remove a process from the process list/n");
 printf("current/t show current runProcess readyList/n");
 printf("exit/t exit this simulation/n");
 printf("help/t get command imformation/n");
 printf("************************************************/n/n");
}

main() {
 queue->head = NULL;
 queue->tail = NULL;
 queue->applyNum = 0;

 log = fopen("Process_log.txt", "w");
 funsInitial();

 helpInfo();
 init();

 char command[20] = {0};
 while (strcmp(command, "exit") != 0) {
  printf("COMMAND>");
  scanf("%s", command);
  
  if (strcmp(command, "exit") == 0) {
   break;
  }else if (strcmp(command, "create") == 0) {
   char name[20] = {'/0'};
   int time = 0;
   scanf("%s %d", name, &time);

   addApplyProcess(name, time);
  } else if (strcmp(command, "remove") == 0) {
   char name[20] = {'/0'};
   scanf("%s", name);
   
   removeProcess(name);
  } else if (strcmp(command, "current") == 0) {
   printCurrent();
  } else if (strcmp(command, "help") == 0) {
   helpInfo();
  } else {
   printf("Enter help to get command information!/n");
  }
 }

 fclose(log);

 return 0;
}

 

 

 

版权声明:本文为博主原创文章,未经博主允许不得转载。

相关文章推荐

c++模拟操作系统进程调度算法(优先数,时间片轮转)

实验一 进程调度 1.目的和要求 进程调度是处理机管理的核心内容。本实验要求编写和调试一个简单的进程调度程序。通过本实验可以加深理解有关进程控制块、进程队列的概念,体会了解优先数和时间片轮转调度...

【操作系统】学习笔记(三)基于时间片轮转的进程调度算法

本文主要用来分享基于时间片轮转的进程调度算法,但是在分享之前,我还是先来整理一下关于进程调度的基本理论。  调度是决定或者安排事物发展次序的策略。进程的调度就是决定哪个进程来使用处理机。 操作系统...

Java模拟最短作业优先、时间片轮转、最高响应比三种进程调度算法

本次试验是使用程序来模拟操作系统中进程调度的三种不同的调度策略,分别为最短作业有限、时间片轮转、最高响应比。 模拟的情况下,进程数为8,进程所需执行时间为随机产生的整数,单位为1S,默认进程同时到达。...

进程调度之时间片轮转调度算法(实验三)

在分时系统中,最简单最常用的就是基于时间片轮转调度算法,时间片轮转调度算法是非常公平的处理机分配方式,让就绪队列的每个进程每次仅运行一个时间片。 1.时间片轮转调度算法的基本原理    在时间片轮转调...

【计算机操作系统】操作系统--时间片轮转(RR)进程调度算法

实验二 间片轮转RR进程调度算法 1、 实验目的 通过这次实验,加深对进程概念的理解,进一步掌握进程状态的转变、进程调度的策略及对系统性能的评价方法。 2、 试验内容 问题描述: 设计程序模...
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:深度学习:神经网络中的前向传播和反向传播算法推导
举报原因:
原因补充:

(最多只允许输入30个字)