一、生产者消费者
#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;
}
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 阿里最新开源QwQ-32B,效果媲美deepseek-r1满血版,部署成本又又又降低了!
· AI编程工具终极对决:字节Trae VS Cursor,谁才是开发者新宠?
· 开源Multi-agent AI智能体框架aevatar.ai,欢迎大家贡献代码
· Manus重磅发布:全球首款通用AI代理技术深度解析与实战指南
· 被坑几百块钱后,我竟然真的恢复了删除的微信聊天记录!