【2016年北京大学自主命题831,第二(3)题】
有四个进程,R1,R2,W1,W2,一个共享缓冲器B,B可以存储一个字符,R1可以从磁盘写入一个字符到B,R2可以从寄存器写入一个字符到B,W1从B中取出一个字符送到打印机打印,W2将字符读出并送往显示器显示,B只能互斥使用。请你设计一个算法完成进程同步,说明你的信号量和初始值,并用PV操作描述代码。
# include <stdio.h>
# include <stdlib.h>
# include <time.h>
# include <sys/types.h>
# include <pthread.h>
# include <semaphore.h>
# include <string.h>
# include <unistd.h>
//semaphores
sem_t mutex,empty,full;
struct data {
int id;
};
//R1
void* R1(void* param){
// while(1){
int id = ((struct data*)param)->id;
sem_wait(&empty);
sem_wait(&mutex);
printf("%d--R1--->B--began\n",id);
sleep(5);
printf("%d--R1--->B--finish\n",id);
sem_post(&mutex);
sem_post(&full);
// }
}
//R2
void* R2(void* param){
// while(1){
int id = ((struct data*)param)->id;
sem_wait(&empty);
sem_wait(&mutex);
printf("%d--R2--->B--began\n",id);
sleep(5);
printf("%d--R2--->B--finish\n",id);
sem_post(&mutex);
sem_post(&full);
// }
}
//W1
void* W1(void* param){
while(1){
int id = ((struct data*)param)->id;
sem_wait(&full);
sem_wait(&mutex);
printf(" B--->W1\n");
sleep(5);
sem_post(&mutex);
sem_post(&empty);
}
}
//W2
void* W2(void* param){
while(1){
int id = ((struct data*)param)->id;
sem_wait(&full);
sem_wait(&mutex);
printf(" B--->W2\n");
sleep(5);
sem_post(&mutex);
sem_post(&empty);
}
}
int main() {
//pthread
pthread_t tid; // the thread identifier 线程标识符
pthread_attr_t attr; //set of thread attributes线程属性集
/* get the default attributes获取默认属性 */
pthread_attr_init(&attr);
//initial the semaphores初始化信号量
sem_init(&mutex, 0, 1);
sem_init(&full, 0, 0);
sem_init(&empty, 0, 1);
int id = 0;
while(scanf("%d", &id) != EOF) {
char role; //producer or consumer
scanf("%c", &role);
struct data* d = (struct data*)malloc(sizeof(struct data));
d->id = id;
if(role == 'r') {
printf(" %d--R1->B--waiting\n",id);
pthread_create(&tid, &attr, R1, d);
}
else if(role == 'R') {
printf(" %d--R2->B--waiting\n",id);
pthread_create(&tid, &attr, R2, d);
}
else if(role == 'w') {
printf(" B->W1--waiting\n");
pthread_create(&tid, &attr, W1, d);
}
else if(role == 'W') {
printf(" B->W2--waiting\n");
pthread_create(&tid, &attr, W2, d);
}
}
//信号量销毁
sem_destroy(&mutex);
sem_destroy(&empty);
sem_destroy(&full);
return 0;
}