📄 os.c
字号:
#include "stdio.h"
#define MAXPRI 100
#define NLL -1
struct messagetp /*消息块类型(信息,指针,发送者号)*/
{int num;
struct messagetp *next;
int pro;
} ;
struct procb /*PCB类型*/
{int id; /*进程号*/
char status; /*进程状态*/
int nextwr; /*等待号*/
int priority; /*优先数*/
struct messagetp *mess; /*消息队指针*/
int inum; /*运行次数*/
char addr; /*返回地址*/
}; /*procb结构体*/
struct semaphorel /*信号量类型(信号量,等待队头号)*/
{int value;
int firstwr;
} ;
struct procb pcb[4]; /*PCB表*/
struct semaphorel sem[3]; /*信号量表*/
char addr; /*当前进程地址*/
int i,seed=0,exe; /*运行次数,随机变量,当前运行进程号*/
int style;
int s1,s2;
void send(int sender,int receiver,int snum) /*发送*/
{struct messagetp *p,*q; /*工作指针*/
p=(struct messagetp*)malloc(sizeof(struct messagetp));
p->num=snum; /*申请消息块,写入缓冲*/
p->next=NULL; /*下一指针置空*/
p->pro=sender; /*置发送者*/
printf("send message to process %d\n",receiver);
printf("process %d already run %d times\n",sender,snum);
q=pcb[receiver].mess; /*q指向接收者消息等待队列首*/
if(q==NULL) pcb[receiver].mess=p; /*q空则p插入队首*/
else
{while(q->next!=NULL)
q=q->next; /*q移到队尾*/
q->next=p;
}
}
void receive(int receiver)
{struct messagetp *p,*q; /*工作指针*/
p=pcb[receiver].mess; /*p指向接收者消息等待队列首 */
while(p!=NULL) /*显示发送者和接收者信息 */
{printf("\n");
printf("receive message from process %d\n",p->pro);
printf("process %d is already run %d times\n",p->pro,p->num);
printf("\n");
q=p; /* 陆续将接收过的的消息块删除并释放 */
p=p->next;
free(q);
}
pcb[receiver].mess=NULL; /*接收完后消息等待队列置空*/
}
void init() /* 初始化*/
{int f,j; /*初始化各进程控制块*/
for(j=1;j<=3;j++)
{pcb[j].id=j;
pcb[j].status='r'; /*进程号,进程状态*/
pcb[j].nextwr=NLL; /*等待指针*/
printf("process %d priority?",j);
scanf("%d",&f); /*读入优先数*/
pcb[j].priority=f;
pcb[j].mess=NULL;
pcb[j].inum=0;
pcb[j].addr='0'; /* 运行次数, 地址*/
}
sem[1].value=1;
sem[1].firstwr=NLL; /*对信号量初始化*/
sem[2].value=1;
sem[2].firstwr=NLL;
exe=NLL; /*当前执行进程号置为空*/
}
float random1() /* 产生0~1之间的随机数 */
{int m; /* seed为int 型,实际值在-32768到32767之间*/
if(seed<0) m=-seed;
else m=seed;
seed=(25173*seed+13849)%65536;
return(m/32767.0);
}
int find() /*选进程*/
{int j,pd,w;
pd=NLL;
w=MAXPRI;
for(j=1;j<=3;j++) /*先在高就绪态中找优先数最小的进程*/
if(pcb[j].status=='r')
if(pcb[j].priority<w)
{w=pcb[j].priority;
pd=j;
}
if(pd==NLL)
for(j=1;j<=3;j++) /* 再在低就绪态中找优先数最小的进程 */
if(pcb[j].status=='t')
if(pcb[j].priority<w)
{w=pcb[j].priority;
pd=j;
}
return pd; /* 返回进程号*/
}
int scheduler() /*调度*/
{int pd;
pd=find(); /*找优先进程 */
if(pd==NLL&&exe==NLL) return(NLL);
else {if(pd!=NLL) /*若有就绪进程则*/
{if(exe==NLL) /* 若当前没有进程执行则 */
{pcb[pd].status='e'; /*新进程置执行态 */
exe=pd;
printf("process %d is executing:\n",exe);
}
else if(pcb[pd].priority<pcb[exe].priority)
{pcb[exe].status='r'; /*原执行进程置高就绪态 */
printf("process %d enter into ready\n",exe);
pcb[pd].status='e'; /*新进程置执行态 */
exe=pd;
printf("process %d is executing\n",exe);
}}
i=pcb[exe].inum; /*恢复现场*/
addr=pcb[exe].addr;
return exe ; /*返回当前执行进程号 */
}
}
void block(int se)
{int w; /*工作指针*/
printf("process %d is blocked\n",exe);
pcb[exe].status='w'; /*置阻塞态*/
pcb[exe].nextwr=NLL;
w=sem[se].firstwr; /*信号量等待队列头指针赋给w */
printf("sem %d first=%d",se,sem[se].firstwr);
printf("pcb%d=%d",w,pcb[w].nextwr);
if(w==NLL) sem[se].firstwr=exe; /*空则当前进程作队头*/
else
{while(pcb[w].nextwr!=NLL)
w=pcb[w].nextwr; /*指针后退到队尾*/
pcb[w].nextwr=exe; /*当前进程链接到队尾*/
}
}
int p(int se,char ad) /*wait操作*/
{sem[se].value=sem[se].value-1; /*信号量减1 */
if(sem[se].value>=0)
return (0); /* 有资源不等待*/
else
{block(se); /* 阻塞到 se 等待队列 */
pcb[exe].inum=i;
pcb[exe].addr=ad; /*保护现场 */
exe=NLL;
return(1); /* 执行进程置空,等待标志置真 */
}
}
void wakeup(int se)
{int w;
w=sem[se].firstwr; /* 队列头指针赋给w*/
if(w!=NLL) /*非空则摘下首块*/
sem[se].firstwr=pcb[w].nextwr; /*重链接 */
pcb[w].status='r'; /*置为高就绪态 */
printf("process %d is waken up\n",w);
}
int v(int se,char ad) /* signal操作*/
{sem[se].value=sem[se].value+1; /* 信号量加1*/
if(sem[se].value>0)
return (0); /*无等待不重新调度*/
else
{wakeup(se); /* 有等待唤醒 se 等待队列的进程*/
pcb[exe].inum=i;
pcb[exe].addr=ad; /*保护现场*/
return (1); /*要重新调度 */
}
}
int timeint(char ad,int k) /*模拟时间片中断*/
{float x; /*x为0~1之间的随机数*/
x=random1();
if(x<0.33&&exe==1) return (0); /*若在各自的时间片不产生中断*/
else if(x<0.66&&exe==2) return(0);
else if(x<1.00&&exe==3) return (0);
else /*否则产生时间片中断*/
{pcb[exe].inum=i; /*保护现场*/
pcb[exe].addr=ad;
pcb[exe].status='t'; /*置为低就绪态*/
sem[k].value=sem[k].value+1;
pcb[exe].nextwr=NLL;
sem[k].firstwr=exe;
printf("sem %d first=%d",k,sem[k].firstwr);
printf("Times silce interrupt:\n");
printf("process %d enter into ready\n",exe);
exe=NLL ; /*执行进程置空*/
return (1); /*中断标志置真*/
}
}
void eexit(int n)
{pcb[n].status='c';
printf("process %d is completed\n",n);
exe=NLL;
}
void process1() /*模拟并发进程1*/
{
if(addr=='a') goto a1;
if(addr=='b') goto b1;
if(addr=='c') goto c1;
if(addr=='d') goto d1;
if(addr=='e') goto e1;
if(addr=='f') goto f1;
while(i<5)
{receive(1); /*1号进程接收消息,无消息继续 */
printf("process1 calls P on semaphore1:\n");
if(p(1,'a')) goto stop1; /*对信号量1进行P操作返回'a'地址*/
a1:;
printf("process1 is executing on its cretical section1\n"); /*入临界区*/
if(timeint('b',1)) goto stop1; /*若时间片到则重新调度*/
b1:;
s1=s1+1;
printf("s1=%d",s1); /*s1是临界资源不是信号量*/
printf("process1 calls V on semaphore1 and quit cretical setion1:\n");
if(v(1,'c')) goto stop1; /* 对信号量1进行V操作,出临界区*/
c1:;
printf("process1 calls P on semaphore2:\n");
if(p(2,'d')) goto stop1; /*对信号量2进行P操作返回'd'地址*/
d1:;
printf("process1 is execting cretical section2:\n");
if(timeint('e',2)) goto stop1;
e1:;
s2=s2+1;
printf("s2=%d",s2);
printf("process1 calls V on semaphore2 and quit cretical section2:\n");
if(v(2,'f')) goto stop1;
f1:;
printf("process 1 cyclen count=%d:\n",i+1);
i=i+1;
send(1,2,i);
send(1,3,i);
/*;*/
}
stop1: if(i<5) goto end1;
eexit(1);
end1:; /* 5次循环后本进程结束*/
}
void process2() /*模拟并发进程2 */
{
if(addr=='a') goto a2;
if(addr=='b') goto b2;
if(addr=='c') goto c2;
if(addr=='d') goto d2;
if(addr=='e') goto e2;
if(addr=='f') goto f2;
while(i<5)
{receive(2);
printf("process2 calls P on semaphore2:\n");
if(p(2,'a')) goto stop2;
a2:;
printf("process2 is executing on its cretical section2:\n");
if(timeint('b',2)) goto stop2;
b2:;
s2=s2+1;
printf("s2=%d",s2);
printf("process2 calls V on semaphore2 and quit cretical setion2:\n");
if(v(2,'c')) goto stop2;
c2:;
printf("process2 calls P on semaphore1:\n");
if(p(1,'d')) goto stop2;
d2:;
printf("process2 is execting cretical section1:\n");
if(timeint('e',1)) goto stop2;
e2:;
s1=s1+1;
printf("s1=%d",s1);
printf("process1 calls V on semaphore1 and quit cretical section1:\n");
if(v(1,'f')) goto stop2;
f2:;
printf("process 2 cyclen count=%d:\n",i+1);
i=i+1;
send(2,1,i);
send(2,3,i);
/*;*/
}
stop2: if(i<5) goto end2;
eexit(2);
end2:;
}
void process3() /*模拟并发进程3*/
{
if(addr=='a') goto a3;
if(addr=='b') goto b3;
if(addr=='c') goto c3;
while(i<5)
{receive(3);
printf("process3 calls P on semaphore2:\n");
if(p(2,'a')) goto stop3;
a3:;
printf("process3 is executing on its cretical section2:\n");
if(timeint('b',2)) goto stop3;
b3:;
s2=s2+1;
printf("s2=%d",s2);
printf("process3 calls V on semaphore2 and quit cretical setion2:\n");
if(v(2,'c')) goto stop3;
c3:;
printf("process3 cyclen count=%d",i+1);
i=i+1;
send(3,1,i);
send(3,2,i);
/*;*/
}
stop3:
if(i<5) goto end3;
eexit(3);
end3:;
}
void main()
{int k;
printf(" C.O.S Example one");
printf("\n");
init();
s1=0;s2=0;
printf("s1=%d,s2=%d",s1,s2);
printf("process1,process2,process3 are all in ready!\n");;
label100: k=scheduler(); /*调用调度程序返回选中进程号*/
printf("k=%d",k);
if(k!=NLL)
switch(k)
{case 1: process1(); goto label100;
case 2: process2(); goto label100;
case 3: process3(); goto label100;
}
else printf("process identifer error!\n");
printf("\n\n");
printf("s1=%d,s2=%d",s1,s2);
printf("\n\n");
printf(" COMPLETED!");
getch();
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -