一、生产者消费者

#include <windows.h>

#include <stdio.h>      //getchar()

#include <stdlib.h>     //rand()

const int SIZE_OF_BUFFER = 10;   //缓冲区长度

int ProductID = 0;               //产品号

int ConsumeID = 0;               //将被消耗的产品号

int in = 0;                      //产品进缓冲区时的下标

int out = 0;                     //产品出缓冲区时的下标

    

int g_buffer[10];               //缓冲区是个循环队列,长度等于SIZE_OF_BUFFER

 

int g_continue = 1;                     //控制程序结束

HANDLE g_hMutex;                            //用于线程间的互斥

HANDLE g_hFullItems;                        //缓冲区中被占用的项

HANDLE g_hEmptyItems;                       //缓冲区中的空项

    

DWORD  WINAPI Producer(LPVOID);              //生产者线程,dword 变量类型的内存占位

DWORD  WINAPI Consumer(LPVOID);              //消费者线程

 

void Produce();

void Append();

void Take();

void Consume();

    

int main()

{

        int i;

        const int PRODUCERS_COUNT =3;       //生产者的个数

        const int CONSUMERS_COUNT =2;       //消费者的个数

 

        //总的线程数

        const int THREADS_COUNT = PRODUCERS_COUNT+CONSUMERS_COUNT;

       

 

        HANDLE *hThreads = (HANDLE*)malloc(sizeof(HANDLE)*THREADS_COUNT);       //各线程的handle

        DWORD *producerID = (DWORD*)malloc(sizeof(DWORD)*PRODUCERS_COUNT);      //生产者线程的标识符

        DWORD *consumerID = (DWORD*)malloc(sizeof(DWORD)*CONSUMERS_COUNT);      //消费者线程的标识符

 

 

        //创建各个互斥信号

        g_hMutex = CreateMutex(NULL,FALSE,NULL);

        g_hFullItems = CreateSemaphore(NULL,0,SIZE_OF_BUFFER,NULL);//创建信号灯,createsemaphore常常被用作多线程同步

        g_hEmptyItems = CreateSemaphore(NULL,SIZE_OF_BUFFER, SIZE_OF_BUFFER,NULL);

       

        //缓冲区初始化

        for (i = 0; i< SIZE_OF_BUFFER;++i)

        {

            g_buffer[i] = -1;   //当值为-1时该项为空

        }   

    

        //创建生产者线程

        for ( i=0;i<PRODUCERS_COUNT;++i){

            hThreads[i]

               =CreateThread(NULL,0,Producer,NULL,0,&producerID[i]);//CreateThread是window提供的API函数

            if (hThreads[i]==NULL) return -1;                       //用此函数可创建一个线程

        }

        //创建消费者线程

        for (i=0;i<CONSUMERS_COUNT;++i){

            hThreads[PRODUCERS_COUNT+i] =CreateThread(NULL,0,Consumer,NULL,0,&consumerID[i]);

            if (hThreads[i]==NULL) return -1;

        }

    

       while(g_continue){

            if(getchar()){  //按回车后终止程序运行

                g_continue = 0;

            }

       } 

      

        return 0;

    }

 

//生产者

 DWORD  WINAPI Producer(LPVOID lpPara)

    {

        while(g_continue){

            int i=rand()%5;

            Sleep(i*1000);

            WaitForSingleObject(g_hEmptyItems,INFINITE);//等待信号灯

            WaitForSingleObject(g_hMutex,INFINITE);

            Produce();

            Append();

            ReleaseMutex(g_hMutex) ;

            ReleaseSemaphore(g_hFullItems,1,NULL);

       }

        return 0;

    }

    

    //消费者

    DWORD  WINAPI Consumer(LPVOID lpPara)

    {

        while(g_continue){

            int i=rand()%5;

            Sleep(i*1000);//该线程释放当前的控制权1500毫秒,让系统调度其他线程

            WaitForSingleObject(g_hFullItems,INFINITE) ;

            WaitForSingleObject(g_hMutex,INFINITE);

            Take();

            Consume();

            ReleaseMutex(g_hMutex);

            ReleaseSemaphore(g_hEmptyItems,1,NULL);

        }

        return 0;

   }

    

    //生产一个产品。简单模拟了一下,仅输出新产品的ID号

    void Produce()

    {

        printf("\nProducing %d ...", ++ProductID);

        printf("Succeed\n");

   }

    

    //把新生产的产品放入缓冲区

    void Append()

    {

              int i;

              printf("Appending a product ...");

      g_buffer[in] = ProductID;

      in = (in+1)%SIZE_OF_BUFFER;

      printf("Succeed\n");

 

   

      //输出缓冲区当前的状态

 

      for (i=0;i<SIZE_OF_BUFFER;++i)

      {

          printf("%d:",i);

 

           if (g_buffer[i]==-1)

               printf("null");

           else

               printf("%d",g_buffer[i]);

             if (i==in) printf("\t<-- 生产");

             if (i==out) printf("\t<-- 消费");

             printf("\n");

        }

    }

   

   //从缓冲区中取出一个产品

   void Take()

   {

       int i;

       printf("\nTaking a product ...");

       ConsumeID = g_buffer[out];

       g_buffer[out]= -1;

       out = (out+1)%SIZE_OF_BUFFER;

       printf("%d--Succeed\n", ConsumeID);

      

       //输出缓冲区当前的状态

       for (i=0;i<SIZE_OF_BUFFER;++i){

           printf("%d:",i);

            if (g_buffer[i]==-1)

                 printf("null");

            else

                printf("%d",g_buffer[i]);

            if (i==in) printf("\t<-- 生产");

            if (i==out) printf("\t<-- 消费");

            printf("\n");

 

       }

    }

   

    //消耗一个产品

    void Consume()

    {

        printf("Consuming %d ", ConsumeID);

        printf("Succeed\n");

    }

    

 

二、处理机调度

#include <stdio.h>

#include <stdlib.h>

#include <string.h>

typedef struct node

{

    char id;

    int cputime;

    int needtime;

    int priority;   }PCB;       //定义PCB结构体 priority是优先级 needtime是估计运行时间 cputime是到达时间

int jobNum = 4;     //作业数量

int batch = 1;      //批处理作业个数

PCB pcb[4];         //pcb数组用来保存所有作业的信息,其大小等于作业数量

PCB memory[1];      //memory数组用来保存被调入到主存中的所有作业信息,其大小等于批处理作业个数

PCB wait[4];        //wait数组用来保存已到达作业,但没能被调入到主存中的作业。其大小等于jobNum-batch

int memoryNum = 0;  //调入至主存中的作业个数。初始化为0

int waitNum = 0;    //等待被调入的作业个数。初始化为0

int MaxTime = 1000; //定义最大的完成时间100

float totalTime = 0;    //保存总的周转时间

void sort(PCB *pcb, int count, char key);

void process(int currentTmp, int nextTmp);

int main(void)

{

    PCB *tmp = (PCB*)malloc(sizeof(PCB));

    char id;

    int cputime, needtime, priority;

    int i, j;

    int current, next;

    printf("输入进程名(char),到达时间(int),所需运行时间(int),优先数(int). 【按到达时间由先到后进行输入】\n");

    for (i = 0; i<jobNum; i++)

    {

        printf("请输入第 %d 个作业的相关信息\n", i);

        scanf("%c%d%d%d", &id, &cputime, &needtime, &priority);

        tmp->id = id;

        tmp->cputime = cputime;

        tmp->needtime = needtime;

        tmp->priority = priority;

        pcb[i] = *tmp;

        fflush(stdin);  }

    for (i = 0; i<jobNum; i++)

    {      printf("作业 %c 的到达时间,所需运行时间,优先数分别为%d, %d, %d:\n", pcb[i].id, pcb[i].cputime, pcb[i].needtime, pcb[i].priority);  }

    //逐个处理作业

    for (i = 0; i < jobNum; i++)

    {

        current = pcb[i].cputime;

        if (i == jobNum - 1)        //说明是最后一个作业

            next = MaxTime;

        else

            next = pcb[i + 1].cputime;  //保存下一个进程到达的时间。注意不能越界

        //先将作业放到wait中,再排序

        wait[waitNum] = pcb[i];

        waitNum++;

        if (waitNum > 1)

            sort(wait, waitNum, 'N');

        /*while (memoryNum < 1 && waitNum>0)        //若当前主存中作业数量小于1,则把当前进程放入到主存中

        {

            memory[memoryNum] = wait[0];

            memory[memoryNum].cputime = current;

            memoryNum++;

            waitNum--;

            for (j = 1; j <= waitNum; j++)

                wait[j - 1] = wait[j];

        }*/

        process(current, next);     //调用process时,memoryNum至少为1

    }//end for

    printf("平均周转时间:%.2f",totalTime/4);

    //在这里输出你的结果,包括列出不同时刻下内存中的运行作业序列、所有作业进入内存的时刻及结束时刻、平均周转时间

    system("pause");

    return 0;

}

void process(int currentTmp, int nextTmp)

{

        int i=0;

        int m,n;

        if(waitNum==0)

            return;

        while(memoryNum<1&&waitNum>0)       //若当前主存中作业数量小于1,则把当前进程放入到主存中

        {

            memory[memoryNum]=wait[0];

            memory[memoryNum].cputime=currentTmp;

            memoryNum++;

            waitNum--;

            for(m=1;m<=waitNum;m++)

                {wait[m-1]=wait[m];         }          }

        int len=memory[0].needtime;

        printf("正在运行%c\n", memory[0].id);

        for(i;i<=len;i++)

        {

            if(currentTmp+i==nextTmp)

            {

                memory[0].needtime=memory[0].needtime-i;

                return;     }                       }

    if(i>len)

    {

        printf("%c完成,到达时刻%d,结束时刻%d\n",memory[0].id,memory[0].cputime,currentTmp+i-1);

        n=(int)(memory[0].id);

        totalTime=totalTime+currentTmp+i-1-pcb[n-65].cputime;

        memoryNum--;

        process(currentTmp +i-1,nextTmp);

        return;             }

}

 

//选择排序算法,若key为'P'则按优先级大的排在数组首,否则为'N'则按所需时间进行短作业优先排序

void sort(PCB *pcb, int count, char key)

{

    int i=0;

    int bs=0;

    int k;

    PCB jh;

    if(key=='P')

    {

        if(count<=1)

        {   return; }

        for(k=1;k<count;k++)

        {

            bs=0;

            for(i;i<count-k;i++)

            {

                if(pcb[i].priority>pcb[i+1].priority)

                {   jh=pcb[i];

                    pcb[i]=pcb[i+1];

                    pcb[i+1]=jh;

                    bs=1;           }

            }

            if(bs==0)

            {   return; }

        }

    }

    else

    {

        if(count<=1)

        {   return; }

        for(k=1;k<count;k++)

        {

            bs=0;

            for (i;i<count-k;i++)

            {

                if (pcb[i].needtime>pcb[i+1].needtime)

                {   jh=pcb[i];

                    pcb[i]=pcb[i+1];

                    pcb[i+1]=jh;

                    bs=1;         }

            }

            if(bs==0)

            {   return;}

        }

 

    }

}

 

三、银行家

#include "stdio.h"

#include<stdlib.h>

#define MAXPROCESS 50       //最大进程数

#define MAXRESOURCE 100     //最大资源数

 

int available[MAXRESOURCE];                 //可用资源数组

int max[MAXPROCESS][MAXRESOURCE];           //最大需求矩阵

int allocation[MAXPROCESS][MAXRESOURCE];    //分配矩阵

int need[MAXPROCESS][MAXRESOURCE];          //需求矩阵

 

int request[MAXPROCESS][MAXRESOURCE];       //进程需要资源数

int finish[MAXPROCESS];                     //系统是否有足够的资源分配给该进程

 

int p[MAXPROCESS];                          //记录序列

int m, n;                                   //m个进程,n个资源

 

void Init();

int Safe();

void Bank();

 

int main()

{

    Init();

    if (Safe()){

        printf("当前状态安全.\n");

    }

    else{

        printf("当前状态不安全.\n");

        system("pause");

        return 0;

    }

    Bank();

    system("pause");

}

 

void Init()                  //初始化算法

{

    int i, j;

    printf("请输入进程的数目:");

    scanf("%d", &m);

    printf("请输入资源的种类:");

    scanf("%d", &n);

    printf("请输入每个进程最多所需的各资源数,按照 %d x %d 矩阵输入\n", m, n);

    for (i = 0; i<m; i++)

        for (j = 0; j<n; j++)

            scanf("%d", &max[i][j]);

 

    printf("请输入每个进程已分配的各资源数,也按照 %d x %d 矩阵输入\n", m, n);

 

    for (i = 0; i<m; i++)

    {

        finish[i] = false;

        for (j = 0; j<n; j++)

        {

            scanf("%d", &allocation[i][j]);

            need[i][j] = max[i][j] - allocation[i][j];

            if (need[i][j]<0)

            {

                printf("您输入的第 %d 个进程所拥有的第 %d 个资源数错误,请重新输入:\n", i + 1, j + 1);

                j--;

                continue;

            }

        }

    }

    printf("请输入各个资源现有的数目:\n");

 

    for (i = 0; i<n; i++)

    {

        scanf("%d", &available[i]);

    }

}

 

void Bank()                  //银行家算法

{

    int r;

    int i = 0;

    printf("请输入你要请求资源的进程:");

    scanf("%d", &r);

    printf("请输入请求的各资源数目:");

    for (i = 0; i < n; i++){

        scanf("%d", &request[r][i]);

        if (request[r][i] > need[r][i] || request[r][i] > available[i]){

            printf("你请求的第%d个资源不符合,请重新输入:", i + 1);

            i--;

            continue;

        }

    }

    for (i = 0; i < n; i++){

        need[r][i] = need[r][i] - request[r][i];

        available[i] = available[i] - request[r][i];

        allocation[r][i] = allocation[r][i] + request[r][i];

    }

    if (Safe()){

        printf("资源可以分配.");

    }

    else{

        printf("本次分配存在安全问题,停止分配.");

    }

}

 

int Safe()                                      //安全性算法

{

    int i, j;

    int *work;

    int *Finish = finish;

    int flag = 0;

    work = (int *)malloc(n*sizeof(int));

    if (!work) return false;

    for (i = 0; i < m; i++){

        work[i] = available[i];

    }

    for (i = 0; i < m; i++){

        if (Finish[i] == false){

            flag = 1;

            for (j = 0; j < n; j++){

                if (need[i][j] > work[j]){

                    break;

                }

            }

            if (j == n){

                Finish[i] = true;

                for (j = 0; j < n; j++){

                    work[j] = allocation[i][j] + work[j];

                }

                i = -1;

                flag = 0;

                continue;

            }

        }

    }

    if (flag == 0){

        for (i = 0; i < m; i++){

            finish[i] = false;

        }

        return true;

    }

    for (i = 0; i < m; i++){

        finish[i] = false;

    }

    return false;

}

 

四、页面置换

#include "stdio.h"

#include "stdlib.h"

typedef struct item

{   int num;        //页号

    int time;       //等待时间,LRU算法会用到这个属性

}Pro;

int pageNum;        //系统分配给作业的主存中的页面数

int memoryNum;      //可用内存页面数

void print(Pro *page1);     //打印当前主存中的页面

int  Search(int num1, Pro *memory1);    //在页面集memory1中查找num1,如果找到,返回其在memory1中的下标,否则返回-1

int main(void)

{

    int i;

    int curmemory;      //调入主存中的页面个数

    int missNum;        //缺页次数

    float missRate;     //缺页率

    char c;             //得到用户的输入字符,来选择相应的置换算法

    Pro *page;          //作业页面集

    Pro *memory;        //内存页面集

    printf("输入系统分配给作业的主存中的页面数:");

    scanf_s("%d", &pageNum);

    printf("输入内存页面数:");

    scanf_s("%d", &memoryNum);

    page = (Pro*)malloc(sizeof(Pro)*pageNum);

    memory = (Pro*)malloc(sizeof(Pro)*memoryNum);

    for (i = 0; i<pageNum; i++)

    {

        printf("第 %d 个页面号为:", i);

        scanf_s("%d", &page[i].num);

        page[i].time = 0;           //等待时间开始默认为0

    }

    do{

        for (i = 0; i<memoryNum; i++)       //初始化内存中页面

        {   memory[i].num = -1;             //页面为空用-1表示

            memory[i].time = -1;            }

        printf("*****f:FIFO页面置换*****\n");

        printf("*****o:OPT页面置换*****\n");

        printf("*****l:LRU页面置换*****\n");

        printf("*****请选择操作类型(f,o,l),按其它键结束******\n");

        fflush(stdin);

        scanf_s("%c", &c);

        i = 0;

        curmemory = 0;

        if (c == 'f')           //FIFO页面置换

        {

            missNum = 0;

            printf("FIFO页面置换情况:   \n");

            for (i = 0; i<pageNum; i++)

            {

                if (Search(page[i].num, memory)<0)//若在主存中没有找到该页面

                {

                    missNum++;

                    memory[curmemory].num = page[i].num;

                    print(memory);

                    curmemory = (curmemory + 1) % memoryNum;

                }

            }//end for

            missRate = (float)missNum / pageNum;

            printf("缺页次数:%d   缺页率:  %f\n", missNum, missRate);

        }//end if

        if (c == 'o')           //OPT页面置换

        {   missNum = 0;

            curmemory = -1;

            printf("OPT页面置换情况:   \n");

            for (i = 0; i<pageNum; i++)

            {   if (Search(page[i].num, memory)<0)//若在主存中没有找到该页面

                {   missNum++;

                    if (memory[(curmemory + 1) % memoryNum].num == -1)

                    {   curmemory = (curmemory + 1) % memoryNum;    }

                    else

                    {   int m = -1, a;

                        int n = memoryNum;

                        for (int j = i + 1; j < pageNum; j++)

                        {   if (Search(page[j].num, memory) >= 0)

                            {   a = Search(page[j].num, memory);

                                if (m != a)

                                {   m = a;

                                    if (memory[m].time != 1)

                                    {   memory[m].time = 1;

                                        n--;                }

                                    if (n == 0)

                                    {   break;  }

                                }

                            }

                        }

                        if (n == 0)

                        {   curmemory = m;

                            for (int j = 0; j < memoryNum; j++)

                            {   memory[j].time = -1;    }

                        }

                        else

                        {   for (int j = 0; j < memoryNum; j++)

                            {   if (memory[j].time == -1)

                                {   curmemory = j;  }

                                else

                                {   memory[j].time = -1;    }

                            }

                        }

                    }

                    memory[curmemory].num = page[i].num;

                    print(memory);

                }

            }//end for

            missRate = (float)missNum / pageNum;

            printf("缺页次数:%d   缺页率:  %f\n", missNum, missRate);

        }//end if

        if (c == 'l')           //LRU页面置换

        {   int j = 0;

            int maxtime, k, a;

            missNum = 0;

            printf("LRU页面置换情况:   \n");

            for (i = 0; i<pageNum; i++)

            {   if (Search(page[i].num, memory)<0)//若在主存中没有找到该页面

                {   missNum++;

                    maxtime = 0;

                    for (k = 1; k < memoryNum; k++)

                    {   if (memory[k].time > memory[maxtime].time)

                        {   maxtime = k;    }

                    }

                    curmemory = maxtime;

                    memory[curmemory].num = page[i].num;

                    print(memory);

                    for (k = 0; k < memoryNum; k++)

                    {   if (k == curmemory)

                        {   memory[k].time = -1;    }

                        else

                        {   memory[k].time++;   }

                    }

                }

                else

                {   a = Search(page[i].num, memory);

                    for (k = 0; k < memoryNum; k++)

                    {   if (k == a)

                        {   memory[k].time = -1;    }

                        else

                        {   memory[k].time++;   }

                    }

                }

            }//end for

            missRate = (float)missNum / pageNum;

            printf("缺页次数:%d   缺页率:  %f\n", missNum, missRate);

        }//end if

    } while (c == 'f' || c == 'l' || c == 'o');

    return 0;

}

void print(Pro *memory1)//打印当前的页面

{   int j;

    for (j = 0; j<memoryNum; j++)

        printf("%d ", memory1[j].num);

    printf("\n");

}

//在页面集memory1中查找num1,如果找到,返回其在memory1中的下标,否则返回-1

int  Search(int num1, Pro *memory1)

{   int j;

    for (j = 0; j<memoryNum; j++)

    {   if (num1 == memory1[j].num)

        return j;   }

    return -1;

}

 

posted on 2022-10-09 17:21  逆凌  阅读(22)  评论(0编辑  收藏  举报