📄 barbershop1.c
字号:
// sleeping barber implementation// UML-CS 91.308 Fall 2005 fredm// based on solution in Tanenbaum// this version requires that you compile with "-lm" flag// so that trig functions included in normal and bursty work.//gcc -o barbershop -lpthread -lm barbershop.c#include <pthread.h>#include <stdio.h>#include <unistd.h>#include <stdlib.h>#include <semaphore.h>#include <sys/time.h>#include <math.h>#define CHAIRS 5 /* # chairs for waiting customers */ sem_t customers; /* # of customers waiting for service */ sem_t barbers; /* # of barbers waiting for customers */ pthread_mutex_t mutex; /* for mutual exclusion */ int waiting = 0; /* customers are waiting (not being cut) */ int cust_num = 1; /* count of potential customers */void barber (void);void customer (void *num);void cut_hair(void);double timediff(struct timeval i, struct timeval j);void seed_random(void);double flat(void);double normal(void);double bursty(void);int main(){ int i; pthread_t barber_t; pthread_t customer_t; struct timeval earlier, now; float delay; seed_random(); // create 1 barber thread pthread_create(&barber_t, NULL, (void *)&barber, NULL); // create customers, with a delay between each gettimeofday (&earlier, (struct timezone *)0); // capture start time for (i=0; i<1000; i++) { pthread_create(&customer_t, NULL, (void *)&customer, (void *)cust_num); cust_num++; delay = 0.010; // delay between arriving customers, in seconds while (1) { // loop until proper amount of real time expires gettimeofday (&now, (struct timezone *)0); if (timediff(now, earlier) >= delay) { earlier.tv_sec = now.tv_sec; earlier.tv_usec = now.tv_usec; break; } } } // stay alive after this happens for the last few customers to be served sleep(3); // this is a place where you can print out the success ratio }double timediff(struct timeval now, struct timeval earlier) { if (now.tv_sec == earlier.tv_sec) return (now.tv_usec - earlier.tv_usec) / 1000000.; else return (1000000 * (now.tv_sec - earlier.tv_sec) + now.tv_usec - earlier.tv_usec) / 1000000.;}void barber(void) { while (1) { sem_wait(&customers); /* go to sleep if # of customers is 0 */ pthread_mutex_lock(&mutex); /* acquire access to waiting */ waiting = waiting - 1; /* decrement count of waiting customers */ sem_post(&barbers); /* one barber is now ready to cut hair */ pthread_mutex_unlock(&mutex); /* release waiting */ cut_hair(); /* cut hair (outside critical region) */ } } void cut_hair (void){ // extra credit: figure out how the barber can know the // customer # of whose hair he's cutting! printf(" Barber: I am cutting the customer's hair...\n "); usleep(100000); // this is the time it takes to cut the hair. // this is 100000 microseconds, or 0.1 second // in other words, the 1 barber can cut 10 customers' hair per second. printf(" Barber: done.\n");}void customer(void *num) { pthread_mutex_lock(&mutex); /* enter critical region */ if (waiting < CHAIRS) { /* if there are no free chairs, leave */ printf("Customer %d: I am getting in line!\n", (int *)num); waiting = waiting + 1; /* increment count of waiting customers */ sem_post(&customers); /* wake up barber if necessary */ pthread_mutex_unlock(&mutex); /* release access to waiting */ sem_wait(&barbers); /* go to sleep if # of free barbers is 0 */ /* be seated and be serviced */ } else { printf("Customer %d: Whatever... I am leaving this joint\n", (int *)num); pthread_mutex_unlock(&mutex); /* shop is full; do not wait */ } pthread_detach(pthread_self()); // we're done; release resources}void seed_random(void){ struct timeval randtime; unsigned short xsub1[3]; gettimeofday (&randtime, (struct timezone *)0); xsub1[0] = (ushort) randtime.tv_usec; xsub1[1] = (ushort)(randtime.tv_usec >> 16); xsub1[2] = (ushort)(getpid()); seed48(xsub1);}// returns an evenly-distributed randomized value// between [0 and 0.2)double flat(){ return drand48() / 5.;} // returns a random value based on bell-shaped curve// use a sine curve; domain is [0, pi)// range will be [0, 1.)// area under sine curve from 0 to pi is 1.double normal(){ return sin(M_PI * drand48()) / M_PI / 2.006999; // experimentally determined to give avg value of 0.1.}// returns upside-down normal// use sine from pi to 2pi, then add 1. to offset// experimentally determined to give avg value of 0.1.double bursty(){ return (sin(M_PI + drand48() * M_PI) + 1.) / 3.591;}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -