⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 thread.cpp

📁 操作系统进程并发模拟系统
💻 CPP
字号:
#include <stdio.h>
#include <stdlib.h>
#include <process.h>
#include <conio.h>
#include <time.h>
#include <malloc.h>
#include <windows.h>
//#include<iostream.h>//
#define DOTIME 0
#define DOMAIN 1
#define TIME_BLOCK 50//50毫秒 
#define TIME_PIECE 10//10毫秒 
#define LASTIME 1
#define TIMEPE 100//10秒 
#define N 1//最大进程需要时间32.7秒 
#define MAX_PRO_NUM 9//最大并发进程数量10个
//定义进程结构
int dealflag = DOMAIN; //全局函数,控制判断执行方式
int cal = 0;
int hand = 0; //切换手动与自动方式
char tmpbuf[20];
char tmpbuf_2[20];
typedef struct Lnode
{
  int id;
  char priority;
  long state; //标志位 
  time_t in_time;
  time_t Fin_time;
  long need_time;
  long do_time;
  Lnode *next;
} Lnode,  *OProC;
OProC ND = NULL; //正在执行的进程 
typedef struct PCB
{
  OProC front;
  OProC trail;
} PCB;
PCB ProG, ProF; //就绪,阻塞、完成队列头指针 


void supervene(void);

//优先级算法
int domainwork(void);

//时间片处理
int dotimework(void);

void process_deal(void);

void random_process_creat(void);

void df_change(void);

void handon(void);
void gotoxy(int x, int y) 
  //cursor an gewuenschte position auf dem bildschirm setzen
{
  CONSOLE_SCREEN_BUFFER_INFO csbiInfo; //variablendklaration
  HANDLE hConsoleOut;

  hConsoleOut = GetStdHandle(STD_OUTPUT_HANDLE);
  GetConsoleScreenBufferInfo(hConsoleOut, &csbiInfo);

  csbiInfo.dwCursorPosition.X = x; //cursorposition X koordinate festlegen
  csbiInfo.dwCursorPosition.Y = y; //cursorposition Y koordinate festlegen
  SetConsoleCursorPosition(hConsoleOut, csbiInfo.dwCursorPosition); 
    //den cursor an die festgelegte koordinate setzen
}

int main()
{
  /*
  printf("");
  //开场介绍两种使用方法
   */
  srand((unsigned)time(NULL));
  int i;
  long j;
  ProG.front = ProG.trail = (OProC)malloc(sizeof(Lnode));
  ProG.front->id = 0; //初始化就绪队列 
  ProG.front->next = NULL;
  ProF.front = ProF.trail = (OProC)malloc(sizeof(Lnode));
  ProF.front->id = 0; //初始化完成队列 
  ProF.front->next = NULL;
  printf("程序说明:\n""所有显示信息将被存入运行结束后的日志文档\n"
    "请先选择一种进程模拟管理执行方式,Enter键默认优先级处理\n""1.优先级\n"
    "2.时间片轮处理\n");
  if ((i = _getch()) == '2')
    dealflag = DOTIME;
  if (dealflag)
    printf("优先级处理方式\n");
  else
    printf("时间片处理方式\n");
  for (i = 3; i >= 0; i--)
  {
    gotoxy(0, 7);
    printf("程序会在倒计时结束后开始执行 %d", i);
    for (j = 0; j < 100000000; j++)
      ;
  }
  system("cls");
  random_process_creat();
  supervene();
  system("Pause");
  return 0;
}


void supervene()
{
  clock_t process_start;
  clock_t process_end;
  Lnode *p,  *q;
  struct tm *timenew;
  long duration;
  while (1)
  {
    //进程列表 
    process_start = clock();
    while (1)
    {
      process_end = clock();
      //printf("end%d\n",process_end);
      if ((duration = (process_end - process_start)) < 0)
        break;
      //printf("duration%d\n",duration);
      if (duration >= TIME_BLOCK)
        break;
      if (dealflag == DOMAIN)
        domainwork();
      else if (dealflag == DOTIME)
        dotimework();
      else
        return ;
    } process_start = clock();
    while (1)
    {
      process_end = clock();
      //printf("end%d\n",process_end);
      if ((duration = (process_end - process_start)) < 0)
        break;
      //printf("duration%d\n",duration);
      if (duration >= TIME_BLOCK)
        break;
      if (hand == 0)
        random_process_creat();
      else
        handon();
    }
    if (!ProG.front->next && ProF.front->next)
    {
      gotoxy(15, 7);
      printf("所有的演示已经结束,请按任意键结束!");
      getch();
      exit(0);
    }
    if (ND && (ND->do_time >= ND->need_time))
    {
      p = ProG.front;
      while (p->next != ND && p->next)
      //删除节点,转向为完成队列
        p = p->next;
      if (p != NULL)
      {
        p->next = ND->next;
        q = ND->next;
        if (ND == ProG.trail)
        {
          ProG.trail = p;
          q = ProG.front->next;
        }
        ProF.trail->next = ND;
        ND->next = NULL;
        time(&ND->Fin_time);
        ProF.trail = ND;
      }
      ND = q;
      system("cls");
    }
    p = ProG.front->next;
    gotoxy(0, 0);
    printf("就绪队列:");
    printf("  执行方式为:");
    if (dealflag == DOMAIN)
      printf("优先级处理");
    else
      printf("时间片轮处理");
    printf("  请按'任意键'进入模式选择");
    gotoxy(0, 1);
    printf("进程ID  进入时间  优先级    预计执行时间(毫秒)  已执行时间(毫秒)\n")
      ;
    while (p)
    {
      timenew = localtime(&p->in_time);
      strftime(tmpbuf, 128, "%H:%M:%S", timenew);
      printf("%2d      %s    %d        %6ld           %6ld\n", p->id, tmpbuf, p
        ->priority, p->need_time, p->do_time);
      p = p->next;
    }
    p = ProF.front->next;
    gotoxy(0, 12);
    printf("完成队列:");
    gotoxy(0, 13);
    printf("进程ID  进入时间    完成时间    预计执行时间(毫秒) \n");
    while (p)
    {
      timenew = localtime(&p->in_time);
      strftime(tmpbuf, 128, "%H:%M:%S", timenew);
      timenew = localtime(&p->Fin_time);
      strftime(tmpbuf_2, 128, "%H:%M:%S", timenew);
      printf("%2d      %s    %s        %6ld    \n", p->id, tmpbuf, tmpbuf_2, p
        ->need_time);
      p = p->next;
    }
    if (kbhit())
      df_change();
  }
}

void df_change()
{
  int i, j;
  char key;
  Lnode *p;
  while (1)
  {
    system("cls");
    printf("请选择:\n");
    printf("1.进程优先权修改\n""2.处理方式的切换\n""3.手动自动进程产生切换\n"
      "4.取消\n");
    if ((key = _getch()) == '1')
    {
      printf("输入方式:进程ID  进程优先级\n");
      scanf("%d %d", &i, &j);
      getchar();
      p = ProG.front->next;
      while (p)
      {
        if (p->id == i)
          break;
        p = p->next;
      }
      if (p)
      {
        p->priority = j;
        printf("修改成功,进程ID%d优先权%d,任意键继续。。。", p->id, p->priority)
          ;
        getchar();
        system("cls");
        return ;
      }
      else
        printf("未找到该进程记录,请重试");
    }
    else if (key == '2')
    {
      if (dealflag == DOMAIN)
        dealflag = DOTIME;
      else
        dealflag = DOMAIN;
      return ;
    }
    else if (key == '3')
    {
      if (hand == 0)
        hand = 1;
      else
        dealflag = 0;
      return ;
    }
    else if (key == '4')
      return ;
  }
}

int domainwork()
{
  Lnode *p,  *q;
  //printf("mainThe function has been token %d times 1\n",++cal);
  //检查阻塞队列
  if (ProG.front == ProG.trail)
    return 0;
  p = ProG.front->next;
  q = p; //就绪队列第一个进程的优先级 
  while (p)
  {
    if (p->priority > q->priority)
      q = p;
    p = p->next;
  }
  ND = q;
  process_deal();
  return 1;
}

int dotimework()
{
  Lnode *p;
  //printf("timeThe function has been token %d times 2\n",++cal);
  if (ProG.front == ProG.trail)
    return 0;
  //就绪队列为空时,退出 
  if (ND == NULL)
    ND = ProG.front->next;
  if (ND->state < TIMEPE)
  {
    process_deal();
    return 0;
  }
  if (ND->state >= TIMEPE)
  {
    ND->state = 0;
    ND = ND->next;
  }
  return 1;
}

void process_deal()
{
  clock_t start, end;
  start = clock();
  long total;
  while (1)
  {
    // printf("进程ID%d正在执行 ",ND->id);
    end = clock();
    if ((total = (end - start)) >= TIME_PIECE)
      break;
  }
  ND->state += total;
  ND->do_time += total; //已执行时间增加 
}

void random_process_creat()
{
  Lnode *p;
  struct tm *timenew;
  int s;
  s = rand();
  gotoxy(70, 0);
  printf("%d", s);
  if ((s <= 1 && cal <= MAX_PRO_NUM) || !cal)
  {
    p = (Lnode*)malloc(sizeof(Lnode));
    p->id = ++cal;
    p->need_time = (long)(rand() *N);
    p->state = 0;
    time(&p->in_time);
    p->do_time = 0;
    p->priority = (int)(rand() % 4);
    ProG.trail->next = p;
    ProG.trail = p;
    ProG.trail->next = NULL;
    timenew = localtime(&p->in_time);
    strftime(tmpbuf, 128, "进入时间为%H:%M:%S", timenew);
    gotoxy(0, 22);
    printf("进程ID为%2d请求被创建,预计执行时间为%7ld毫秒", p->id, p->need_time)
      ;
    gotoxy(0, 23);
    printf(tmpbuf);
  } 
}

void handon()
{
  Lnode *p;
  struct tm *timenew;
  p = (Lnode*)malloc(sizeof(Lnode));
  p->id = ++cal;
  p->need_time = (long)(rand() *N);
  p->state = 0;
  time(&p->in_time);
  p->do_time = 0;
  p->priority = (int)(rand() % 4);
  ProG.trail->next = p;
  ProG.trail = p;
  ProG.trail->next = NULL;
  timenew = localtime(&p->in_time);
  strftime(tmpbuf, 128, "进入时间为%H:%M:%S", timenew);
  gotoxy(0, 22);
  printf("进程ID为%2d请求被创建,预计执行时间为%7ld毫秒", p->id, p->need_time);
  gotoxy(0, 23);
  printf(tmpbuf);
  hand = 0;
}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -