?? wros2new.cpp
字號:
// MyOSnew.cpp : Defines the entry point for the console application.
//
//生產者--消費者問題
#include "stdafx.h"
#include <stdio.h>
#include <ctype.h>
#define TRUE 1
#define FALSE 0
#define NIL -1
#define MAX 6
#define Length 3//緩沖池長度
struct tagpcb /* 進程控制塊的結構 */
{
int id; /* 進程內部標識符 */
char status; /* 進程狀態 */
int priority; /* 進程初始優先數 */
int nptr; /* 進程隊列指針 */
char save; /* 斷點保存 */
}pcb[MAX];
struct tagsem /* 信號量的結構 */
{
int value; /* 信號量的值 */
int L; /* 進程鏈表指針 */
}sem[2];
int addr,run,m,k[MAX],jj[MAX];
/* addr為當前進程程序的執行地址;run為執行態進程的內部標識符;m為單緩沖區 */
int in,out,buffer[Length];//in是緩沖池輸入指針,out是緩沖池輸出指針,buffer[3]是緩沖池
void init(); /* 初始化模塊 */
int scheduler();
//生產者進程
int processA();
int processB();
int processC();
//消費者進程
int processD();
int processE();
int processF();
void block(int *L);
void wakeup(int *L);
main()
{
int k,i,s;
char n[MAX];
printf("按優先級從大到小的順序輸入%d個進程的名稱 :\n",MAX);
goto l1;
l2:printf("錯誤! 請重新輸入 :\n");
l1:gets(n);
for(i=0;i<MAX;i++)
{if(!(isalpha(n[i])))goto l2;
n[i]=(n[i]>='a'&&n[i]<='z')?(n[i]-32):n[i];
}
for(i=0;i<MAX;i++)
switch(n[i])
{
case 'A':
case 'B':
case 'C':
case 'D':
case 'E':
case 'F':break;
default: goto l2;
}
for(i=0;i<MAX-1;i++)
for(k=i+1;k<MAX;k++)
if(n[i]==n[k])goto l2;
for(i=0;i<MAX;i++)
switch(n[i])
{case 'A':jj[i]=0;break;
case 'B':jj[i]=1;break;
case 'C':jj[i]=2;break;
case 'D':jj[i]=3;break;
case 'E':jj[i]=4;break;
case 'F':jj[i]=5;break;
}
init();
for(s=0;s<2;s++)
printf("s%d.value=%d,s%d.L=NIL\n",s,sem[s].value,s);
printf("進程A:pcb1:pcb[%d], 進程B:pcb2:pcb[%d], 進程C:pcb3:pcb[%d]\n",pcb[0].id,pcb[1].id,pcb[2].id);
printf("進程D:pcb4:pcb[%d], 進程E:pcb5:pcb[%d], 進程F:pcb6:pcb[%d]\n",pcb[3].id,pcb[4].id,pcb[5].id);
printf("各進程優先級: A=%d,B=%d,C=%d, D=%d,E=%d,F=%d\n",
pcb[0].priority,pcb[1].priority,pcb[2].priority,pcb[3].priority,pcb[4].priority,pcb[5].priority);
for( ; ; )
{ printf("\n進程運行狀態:A '%c' B '%c' C '%c' ",pcb[0].status,pcb[1].status,pcb[2].status);
printf("D '%c' E '%c' F '%c'\n",pcb[3].status,pcb[4].status,pcb[5].status);
if(scheduler() != NIL)
continue;
else
{
printf("\n進程運行狀態:A '%c' B '%c' C '%c' ",pcb[0].status,pcb[1].status,pcb[2].status);
printf("D '%c' E '%c' F '%c'\n",pcb[3].status,pcb[4].status,pcb[5].status);
break;
}
} //end of for
printf("所有進程全部完成,系統停止。\n");
printf(" * * * * * 結束 * * * * *\n");
return 0;
}
void init()
{
int j;
for(j=0;j<MAX;j++) /* 進程控制塊初始化 */
{
pcb[j].id=j;
pcb[j].status='R';
pcb[j].nptr=NIL;
pcb[j].save='F';
}
for(j=0;j<MAX;j++) /* 根據要求設置初始優先數 */
pcb[jj[j]].priority=j+1;
sem[0].value=Length;sem[0].L=NIL; /* 信號量初始化 */
sem[1].value=0;sem[1].L=NIL;
k[0]=k[1]=k[2]=4;k[3]=k[4]=k[5]=4; /* 設置循環次數 */
//m=0;
buffer[0]=buffer[1]=buffer[2]=0; /* 緩沖區清零 */
}
int wait(int i)
{
// s->value=s->value-1;
sem[i].value=sem[i].value-1;
printf("wait 信號量sem[%d],...sem[%d].value=%d\n",i,i,sem[i].value);
// printf("s->value=%d\n",s->value);
if(sem[i].value<0) //wait failed,process will be blocked
{
block(&sem[i].L);
return 1;
}
else
return 0;//wait succeed
}
int signal(int i)//i決定是哪個信號量
{
//s->value=s->value+1;
sem[i].value=sem[i].value+1;
printf("signal 信號量sem[%d],...sem[%d].value=%d\n",i,i,sem[i].value);
if(sem[i].value<=0)//還有阻塞的進程,將他們喚醒
{
printf("還有阻塞的進程,將他們喚醒\n");
wakeup(&sem[i].L);
return 1;
}
else
{
printf("沒有阻塞的進程\n");
return 0;//沒有阻塞的進程
}
}
/****************六個進程函數A,B,C,D,E,F********************/
int processA()
{
int n;
// n=k[0];//將要輸入到緩沖區m的數暫存在n中
if(addr=='I') goto i1;//判斷是首次進入還是中斷喚醒后進入
f1: printf("生產者進程A正在運行...\n");
if(wait(0)==0)//wait succeed
{
printf("processA wait succeed\n");
goto i2;//可以將計算結果送入緩沖區
// return signal(&sem[1]);//-1還有阻塞的進程
//0沒有阻塞的進程
}
else//wait failed
{
printf("processA wait failed\n");
// pcb[0].status='B';//進程A阻塞,要保存斷點
return 1;
}
i1:
printf("生產者進程A被喚醒...\n");//中斷喚醒后的入口地址
i2:n=k[0];//將要輸入到緩沖區m的數暫存在n中
printf("生產者進程A將計算結果送入緩沖區buffer[%d]=%d\n",in,n);
//m=n;
buffer[in]=n;
in=(in+1)%Length;
signal(1); //-1還有阻塞的進程
//0沒有阻塞的進程
if(--k[0]==0)
return 0;//完成標志
else
// goto f1;
{
pcb[0].status='R';//'E'-->'R',進入下一次的優先權比較
return 2;
}
}
//--------------------------------------------------
int processB()
{
int n;
// n=2*k[1];//將要輸入到緩沖區m的數暫存在n中
if(addr=='I') goto i1;//判斷是首次進入還是中斷喚醒后進入
f1: printf("生產者進程B正在運行...\n");
if(wait(0)==0)//wait succeed
{
printf("processB wait succeed\n");
goto i2;//可以將計算結果送入緩沖區
// return signal(&sem[1]);//-1還有阻塞的進程
//0沒有阻塞的進程
}
else//wait failed
{
printf("processB wait failed\n");
// pcb[0].status='B';//進程A阻塞,要保存斷點
return 1;
}
i1:
printf("生產者進程B被喚醒...\n");//中斷喚醒后的入口地址
i2:n=4*k[1];//將要輸入到緩沖區m的數暫存在n中
printf("生產者進程B將計算結果送入緩沖區buffer[%d]=%d\n",in,n);
//m=n;
buffer[in]=n;
in=(in+1)%Length;
signal(1); //-1還有阻塞的進程
//0沒有阻塞的進程
if(--k[1]==0)
return 0;//完成標志
else
// goto f1;
{
pcb[1].status='R';
return 2;
}
}
//-----------------------------------------------------
int processC()
{
int n;
// n=3*k[2];//將要輸入到緩沖區m的數暫存在n中
if(addr=='I') goto i1;//判斷是首次進入還是中斷喚醒后進入
f1: printf("生產者進程C正在運行...\n");
if(wait(0)==0)//wait succeed
{
printf("processC wait succeed\n");
goto i2;//可以將計算結果送入緩沖區
// return signal(&sem[1]);//-1還有阻塞的進程
//0沒有阻塞的進程
}
else//wait failed
{
printf("processC wait failed\n");
// pcb[0].status='B';//進程A阻塞,要保存斷點
return 1;
}
i1:
printf("生產者進程C被喚醒...\n");//中斷喚醒后的入口地址
i2: n=5*k[2];//將要輸入到緩沖區m的數暫存在n中
printf("生產者進程C將計算結果送入緩沖區buffer[%d]=%d\n",in,n);
//m=n;
buffer[in]=n;
in=(in+1)%Length;
signal(1); //-1還有阻塞的進程
//0沒有阻塞的進程
if(--k[2]==0)
return 0;//完成標志
else
// goto f1;
{
pcb[2].status='R';
return 2;
}
}
//-----------------------------------------------------
int processD()
{
if(addr=='I') goto i1;//判斷是首次進入還是中斷喚醒后進入
f1: //k[2]--;//首次進入
printf("消費者進程D正在運行...\n");
if(wait(1)==0)//wait succeed
{
printf("processD wait succeed:%d\n",sem[1].value);
goto i2;
// return signal(&sem[0]);//-1還有阻塞的進程
//0沒有阻塞的進程
}
else//wait failed
{
printf("processD wait failed\n");
// pcb[2].status='B';//進程C阻塞,要保存斷點
return 1;
}
i1:
printf("消費者進程D被喚醒...\n");//中斷喚醒后的入口地址
i2:
printf("消費者進程D將打印計算結果: ");
// printf("m=%d\n",m);
printf("buffer[%d]=%d\n",out,buffer[out]);
out=(out+1)%Length;
signal(0); //-1還有阻塞的進程
//0沒有阻塞的進程
if(--k[3]==0)
return 0;
else
// goto f1;
{
pcb[3].status='R';
return 2;
}
}
//------------------------------------------------------
int processE()
{
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -