# BUAA OS 作业：进程同步与PV操作

## 第一题

int read_count = 0, write_count = 0;
semaphore read_mutex = 1, write_mutex = 1;
semaphore data_mutex = 1;  // 互斥访问共享数据

void writer() {
while (true) {
P(write_count);
V(write_count);

P(data_mutex);
// writing
V(data_mutex);

P(write_count);
V(write_count);
}
}

while (true) {

}
}


## 第二题

int wait_num = 0, eat_num = 0;
bool no_chairs = false;
semaphore mutex = 1; //互斥访问上面三个变量
semaphore block = 0;

void eat() {
while (true) {
P(mutex);
if (no_chairs) { // 5个位置都满了，需要等所有人吃完
wait_num++;  // mutex保证互斥
P(block);
} else {
eat_num++;
no_chairs = (eat_num == 5);
V(mutex);
}

// eat

P(mutex);
eat_num--;
if (eat_num == 0) {
int n = min(wait_num, 5);
wait_num -= n;
eat_num += n;
no_chairs = (n == 5);
while (n--) V(block);
}
V(mutex);
}
}


## 第三题

var mutex: semaphore := 1;  // 互斥信号量，互斥访问这N个单元
var even: semaphore := 0;  // 奇数数据的同步信号量，表示已占用缓冲区中偶数个数；
var odd: semaphore := 0;  // 偶数数据的同步信号量，表示已占用缓冲区中奇数个数；
var empty: semaphore := N;  // 缓冲区同步信号量，表示空闲缓冲区个数

// p1
begin
repeat
P(empty);
var number: integer := produce();
P(mutex);
put(number);
V(mutex);
if (number % 2 = 0) then
V(even);
else
V(odd);
until false;
end

// p2
begin
repeat
P(odd);  // 不能先P(mutex)
P(mutex);
var ret: integer := getOdd();
V(mutex);
V(empty);
countodd();
until false;
end

//p3
begin
repeat
P(even);
P(mutex);
var ret: integer := getEven();
V(mutex);
V(empty);
counteven();
until false;
end.


## 第四题

/* 优先级：搜索 > 插入 > 删除 */
int search_num = 0;
semaphore has_searchers = 1;
semaphore has_inserters = 1;
semaphore search_num_mutex = 1;  // 互斥访问search_num

void del() {
while (true) {
P(has_searchers);  //不能有其他搜索进程
P(has_inserters);  //不能有其他插入进程
// 上面两个信号量已经保证了del访问临界资源互斥，不需要另外新加信号量
/* delete */
V(has_inserters);
V(has_searchers);
}
}

void search() {
while (true) {
P(search_num_mutex);
if (search_num++ == 0) {
V(search_num_mutex);
P(has_searchers);
} else V(search_num_mutex);
/* search */
P(search_num_mutex);
if (--search_num == 0) {
V(has_searchers);
}
V(search_num_mutex);
}
}

void insert() {
while (true) {
P(has_inserters);  // 保证insert之间互斥
// 此时一定只有一个insert进程执行，不需对search进程数目限制，同时此时没有delete进程
/* insert */
V(has_inserters);
}
}

posted @ 2022-05-03 20:01  NormalLLer  阅读(191)  评论(1编辑  收藏  举报