?? lift simulator.c
字號:
/********************
159335 Assignment 2 lift simulator program
********************/
#include <stddef.h> // 159.335 Assignment 2
#include <stdio.h> // Lift Simulator - M.Johnson 2000
#include <stdlib.h> // This was written for GCC but it
#include <windows.h> // may also work with Borlandc
#include <conio.h> // and Visual C++
// lines starting with --- are unfinished
#define semaphore HANDLE
void wait(semaphore h) { // wait for a semaphore
WaitForSingleObject( h, MAXLONG);
}
void signal(semaphore h) { // signal a semaphore
ReleaseSemaphore(h,1,NULL);
}
semaphore create(int v) { // create a semaphore with value v
return CreateSemaphore(NULL,(long)v, MAXLONG, NULL);
}
//
// The size of the buliding
//
#define NLIFTS 4 /* the number of lifts in the buliding */
#define NFLOORS 20 /* the number of floors in the building */
#define NPEOPLE 20 /* the number of people in the building */
#define MAXNOINLIFT 10 /* maximum lift capacity */
//
// Some times (all in milliseconds)
//
//#define LIFTSPEED 50
//#define GETINSPEED 50
//#define GETOUTSPEED 50
//#define PEOPLESPEED 100
#define LIFTSPEED 0 /* the time it takes for the lift to move one floor */
#define GETINSPEED 0 /* the time it takes to get into the lift */
#define GETOUTSPEED 0 /* the time it takes to get out of the lift */
#define PEOPLESPEED 1 /* the maximum time a person spends on a floor */
//
// Directions
//
#define UP 1
#define DOWN -1
#define rnd(i) (rand()%(i)) /* a random number from 0..i-1 inclusive */
int rand_seed=123456;
#define randomise() srand(rand_seed);rand_seed=rand();
//
// Information about a floor in the building
//
typedef struct {
int waitingtogoup; /* the number of people waiting to go up */
int waitingtogodown; /* the number of people waiting to go down */
semaphore up_arrow; /* people going up wait on this */
semaphore down_arrow; /* people going down wait on this */
} Floor_info;
//
// Information about a lift
//
typedef struct {
int no; /* which lift is it */
int position; /* which floor it is on */
int direction; /* going UP or DOWN */
int peopleinlift; /* number of people in the lift */
int stops[NFLOORS]; /* for each stop how many people are waiting to get off */
semaphore stopsem[NFLOORS]; /* people in the lift wait on one of these */
} Lift_info;
//
// Some global variables
//
semaphore mutex,//mutex to protect critical sections
InLift[NFLOORS];//people in each floor, wait for this to get into lift
Floor_info floor[NFLOORS];
Lift_info *GetInLift;//global variable, tell person which lift to get in
//
// print a character c on the screen at position (x,y)
//
void char_at_xy(int x,int y,char c) {
wait(mutex);//make it into critical section, avoid each thread want to draw on screen at the same time
#ifdef __GNUC__
gotoxy(x,y);
#else
gotoxy(x+1,y+1);
#endif
Sleep(1); // slow things down for NT
printf("%c",c); /* the char itself */
signal(mutex);
}
//
// Tell everybody that is waiting to go in a certain direction
// to get into the lift. If the lift was empty then move it in the correct direction.
//
void getintolift(Lift_info *l,int direction) {
int *waiting;
semaphore *s;
if(direction==UP) { /* if going up */
s=&floor[l->position].up_arrow; /* use this semaphore */
waiting=&floor[l->position].waitingtogoup; /* and this is the number waiting */
}
else { /* if going down */
s=&floor[l->position].down_arrow; /* use this semaphore */
waiting=&floor[l->position].waitingtogodown; /* and this is the number waiting */
}
wait(InLift[l->position]);//aaaa block the semaphore, people want to get in
// make it into critical section, people ready to get in
while(*waiting) { /* for all people waiting */
if(!l->peopleinlift) /* if the lift is empty */
l->direction=direction; /* set direction */
if(l->peopleinlift<=MAXNOINLIFT && *waiting) {
l->peopleinlift++; /* one more in the lift */
char_at_xy(NLIFTS*4+floor[l->position].waitingtogodown+floor[l->position].waitingtogoup,
NFLOORS-l->position,' '); /* erase from screen */
(*waiting)--; /* one less waiting */
Sleep(GETINSPEED); /* wait a short time */
if (l) {
wait(mutex); // enter critical section, protect lift info
GetInLift=l; /* tell the person which lift it is, assign to the gobal variable */
signal(mutex); /* and wake them up*/
}
else return;
}
else {
break;
}
}
signal(*s); //wake up up_arrow or down_arrow,this two semaphore will be 1, others can go up or down wait for this
signal(InLift[l->position]); //release this level of people waiting
}
//
// A lift
//
unsigned long lift_thread(void *p) {
Lift_info l;
int i;
int no=(int)p;
l.no=no; /* set the no for this lift */
l.position=0; /* set the initial position */
l.direction=1; /* and direction */
l.peopleinlift=0; /* empty */
randomise();
for(i=0;i<NFLOORS;i++) {
l.stops[i]=0; /* nobody is waiting in the lift to go anywhere */
l.stopsem[i]=create(0);
InLift[i]=create(1);//initialise each level of InLift by 1, ready for wait
}
Sleep(rnd(1000)); /* wait for a while */
while(1) { /* do forever */
char_at_xy(no*4+1,NFLOORS-l.position,0xdb); /* draw current position of lift */
Sleep(LIFTSPEED); /* wait a while */
while (l.stops[l.position]!=0) { /* drop off all passengers */
l.peopleinlift--; /* one less in lift */
l.stops[l.position]--; /* one less waiting */
Sleep(GETOUTSPEED); /* wait a while */
signal(l.stopsem[l.position]); /* tell them to get out */ //aaa when it is in position, get out
if(!l.stops[l.position]) /* if it was the last one */
char_at_xy(no*4+1+2,NFLOORS-l.position,' '); /* remove the - */
}
if(l.direction==UP || !l.peopleinlift) /* if the lift is going up or is empty */
getintolift(&l,UP); /* pick up passengers waiting to go up */
if(l.direction==DOWN || !l.peopleinlift) /* if the lift is going down or is empty */
getintolift(&l,DOWN); /* pick up passengers waiting to go down */
char_at_xy(no*4+1,NFLOORS-l.position,(char)(l.direction+1?' ':0xb3)); /* erase the lift on the screen */
l.position+=l.direction; /* move it */
if(l.position==0 || l.position==NFLOORS-1) /* if it is at the top or bottom */
l.direction=-l.direction; /* change direction */
}
}
//
// A person
//
unsigned long person_thread(void *p) {
int from=0,to; /* start on the ground floor */
Lift_info *l;
randomise();
while(1) { /* stay in the building forever */
Sleep(rnd(PEOPLESPEED)); /* work for a while */
do
to=rnd(NFLOORS);
while(to==from); /* pick a different floor to go to*/
if(to>from) { /* if we are going up */
floor[from].waitingtogoup++;
char_at_xy(NLIFTS*4+ floor[from].waitingtogoup
+floor[from].waitingtogodown,NFLOORS-from,0xdc);
wait(floor[from].up_arrow); /* wait for the lift to arrive */
}
else { /* if we are going down */
floor[from].waitingtogodown++;
char_at_xy(NLIFTS*4+ floor[from].waitingtogoup
+floor[from].waitingtogodown,NFLOORS-from,0xdc);
wait(floor[from].down_arrow); /* wait for the lift to arrive */
}
if(GetInLift) {
wait(mutex);//protect lift info, critical section
l=GetInLift; /* which lift are we geting in to */ //aaaa
l->stops[to]++; /* press the button for the floor we want */
signal(mutex);
}
else return;
if(l->stops[to]==1) /* light up the button if we were the first */
char_at_xy(l->no*4+1+2,NFLOORS-to,'-');
wait(l->stopsem[to]); /* wait until we get to the right floor */ //wait until people get out in the 'to' position
from=to; /* we have reached our destination */
}
}
//
// Print the building on the screen
//
void printbuilding(void) {
int l,f;
clrscr(); /* clear the screen added for borlandc */
_setcursortype(_NOCURSOR); // added for borlandc and gcc
printf("\xda");
for(l=0;l<NLIFTS-1;l++) /* roof */
printf("\x0c4\x0c2\x0c4\x0c2");
puts("\x0c4\x0c2\x0c4\x0bf");
for(f=NFLOORS-1;f>=0;f--)
for(l=0;l<NLIFTS;l++) { /* floors */
printf("\x0b3\x0b3\x0b3 ");
if(l==NLIFTS-1)
puts("\x0b3");
}
printf("Lift Simulation - Press CTRL-Break to exit");
}
//
// main starts the threads and then just sits there.
//
int main() {
unsigned long i,id;
/* initialise any other semaphores */
mutex=create(1); // initialise mutex by 1, ready for wait
for(i=0;i<NFLOORS;i++) {
floor[i].waitingtogoup=0; /* initialise the building */
floor[i].waitingtogodown=0;
floor[i].up_arrow=create(0);
floor[i].down_arrow=create(0);
}
printbuilding(); /* print the buildong on the screen */
for(i=0;i<NLIFTS;i++) /* create the lift threads */
CreateThread(NULL,0,lift_thread,(void *)i,0,&id);
for(i=0;i<NPEOPLE;i++) /* create the people threads */
CreateThread(NULL,0,person_thread,(void *)i,0,&id);
Sleep(86400000); /* go to sleep for 86400 seconds (one day) */
return(1);
}
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -