第一关:生产者与消费者问题
信号量是4个,除了题目里已经给出的2个之外,还有分别针对生产者和消费者的mutex。
切记要把四个信号量在同一行中定义!
#include #include #include #include #include #include #define N8#define PRODUCT_NUM 15int buffer[N], readpos = 0, writepos = 0;sem_t full, empty, mutexC, mutexP; //添加生产者和消费者的mutexvoid sleep_random(int t) {sleep((int)(t * (rand() / (RAND_MAX *1.0))));}#define PRODUCER_CNT 5#define CONSUMER_CNT 5void *produce(void *idx){int id =*((int*)idx); //创建线程的idint i;for (i = 0; i = N)writepos = 0;printf("produce:%d\n", 1000*(id) + i + 1);sem_post(&mutexC);sem_post(&mutexP);sem_post(&full);}}void *consume(){int i;for (i = 0; i = N)readpos = 0;sem_post(&mutexP);sem_post(&empty);}}int main(){int res, i;pthread_t t1[PRODUCER_CNT],t2[CONSUMER_CNT];for (i = 0; i < N; i++)buffer[i] =- 1;srand((int)time(0));sem_init(&full, 0, 0);sem_init(&empty, 0, N);sem_init(&mutexP, 0, 1);sem_init(&mutexC, 0, 1);for (i = 0; i < PRODUCER_CNT; i++)res = pthread_create(&t1[i], NULL, produce, &i);if (res != 0){perror("failed to create thread");exit(1);}for (i = 0; i < CONSUMER_CNT; i++)res = pthread_create(&t2[i], NULL, consume, NULL);if (res != 0){perror("failed to create thread");exit(1);}void* resj;for(i = 0; i < PRODUCER_CNT; i++){pthread_join(t1[i],&resj);}for(i = 0; i < CONSUMER_CNT; i++){pthread_join(t2[i],&resj); }return 0;}
第二关:三个并发进程
1. 不要看到长空格就写\t,要换成8个空格才能通过(以下代码使用了\t)
2. 注意几个信号量的请求顺序
#include #include #include #include #include #include #define LIMIT20#define M5#define N8/************************************/sem_t mtp,mtq,mtr,full1,empty1,empty2,full2;int buffer1[M],buffer2[N];/************************************/void sleep_random(int t) {sleep((int)(t * (rand() / (RAND_MAX *1.0))));}void *P(){int i;for (i = 0; i < LIMIT; i++){sleep_random(2);/************************************/sem_wait(&empty1);sem_wait(&mtq);sem_wait(&mtp);buffer1[i%M]=i+1;printf("P sends:\t%d\n",i+1);sem_post(&mtp);sem_post(&mtq);sem_post(&full1);/************************************/}}void *Q(){int i, data;for (i = 0; i < LIMIT; i++){sleep_random(2);/************************************/int t;sem_wait(&full1);sem_wait(&mtp);sem_wait(&mtq);t=buffer1[i%M];sem_post(&mtq);sem_post(&mtp);sem_post(&empty1);sem_wait(&empty2);sem_wait(&mtr);sem_wait(&mtq);buffer2[i%N]=t;sem_post(&mtq);sem_post(&mtr);sem_post(&full2);/************************************/}}void *R(){int i;for (i = 0; i < LIMIT; i++){sleep_random(2);/************************************/sem_wait(&full2);sem_wait(&mtq);sem_wait(&mtr);printf("R receives: %d\n",buffer2[i%N]);sem_post(&mtr);sem_post(&mtq);sem_post(&empty2);/************************************/}}int main(){int i;pthread_t t1, t2;for (i = 0; i < M; i++)buffer1[i] =- 1;for (i = 0; i < N; i++)buffer2[i] =- 1;srand((int)time(0));/************************************/sem_init(&mtp,0,1);sem_init(&mtq,0,1);sem_init(&mtr,0,1);sem_init(&full1,0,0);sem_init(&empty1,0,M);sem_init(&full2,0,0);sem_init(&empty2,0,N);/************************************/pthread_create(&t1, NULL, P, NULL);pthread_create(&t2, NULL, Q, NULL);R();return 0;}
第三关:理发师问题
可以理解为缓存容量分别为2,1,1的第二题。信号量的排序需要注意。
#include #include #include #include #include #include #define SEAT_NUM2#define CUSTOMER_NUM5/************************************/sem_t empty,full,empty2,full2,mtb,mtw;//mutex lock for the barber and waiting roomint buffer[SEAT_NUM], cur_serv, readpos = 0, writepos = 0;//waiting room/************************************/void sleep_random(int t) {sleep((int)(t * (rand() / (RAND_MAX *1.0))));}void *barber(){while(5){/************************************/sem_wait(&full);buffer[readpos++] = -1;if (readpos >= SEAT_NUM){readpos = 0;}sem_post(&empty);sem_wait(&empty2);/************************************/printf("barber: start cutting\n");sleep_random(3);printf("barber: finish cutting\n");/************************************/sem_post(&full2);/************************************/}}void *customer(void *id){const int myid = *(int*)id;sleep_random(2);printf("customer %d: enter waiting-room\n", myid);/************************************/sem_wait(&empty);sem_wait(&mtw);/************************************/printf("customer %d: sit down\n", myid);/************************************/buffer[writepos++] = myid;if (writepos >= SEAT_NUM)writepos = 0;sem_post(&mtw);sem_wait(&mtb);/************************************/printf("customer %d: enter cutting-room and sit down\n", myid);/************************************/cur_serv = myid;sem_post(&full);sem_wait(&full2);/************************************/printf("customer %d: bye\n", myid);/************************************/sem_post(&mtb);sem_post(&empty2);/************************************/}int main(){int i, id[CUSTOMER_NUM];pthread_t t[CUSTOMER_NUM];srand((int)time(0));/************************************/sem_init(&empty,0,SEAT_NUM);sem_init(&full,0,0);sem_init(&full2,0,0);sem_init(&empty2,0,1);sem_init(&mtb,0,1);sem_init(&mtw,0,1);/************************************/for (i = 0; i < CUSTOMER_NUM; i++){id[i] = i + 1;pthread_create(&t[i], NULL, customer, &id[i]);}barber();return 0;}