1
由于此程序使用 fork,故 child process 和 parent process 的内存是隔离的,所以 child value = 5, parent value = 0. 并且由于 parent 在 wait child,所以 parent 一定在 child 后才输出。又由于 child 是由 parent fork 得来的并且没有 exec,故它们使用同一个 stdout,所以会输出在一起。
下次出这种题的时候能不能给文字版本而不是给一张图片让我们自己去识图。
2
给出的是读优先的解决方案:读者在有读者时可以继续读。
写优先:
semaphore resource = 1;
semaphore rmutex = 1;
semaphore wmutex = 1;
int readcount = 0;
int writecount = 0;
//writer
while (true) {
wait(wmutex);
writecount++;
if (writecount == 1)
wait(readTry);
signal(wmutex);
wait(resource);
// writing is performed
signal(resource);
wait(wmutex);
writecount--;
if (writecount == 0)
signal(readTry);
signal(wmutex);
}
//reader
while (true) {
wait(readTry);
wait(rmutex);
readcount++;
if (readcount == 1)
wait(resource);
signal(rmutex);
signal(readTry);
// reading is performed
wait(rmutex);
readcount--;
if (readcount == 0)
signal(resource);
signal(rmutex);
}
思路是写者也维护一个锁,有写者准备写时新的读者不能进入。
3
采用 lab1 的 6.19.6 内核代码。
struct atomic_t:一个整数,定义于 linux/types.h
int arch_atomic_read(const atomic_t*), void arch_atomic_set: 原子读写,定义于 asm/atomic.h 和 include/compiler.h,使用前后添加 barrier() 再加汇编读写完成。
void arch_atomic_add, void arch_atomic_sub, bool arch_atomic_sub_and_test, \ldots:同上,其余原子操作的定义,同样在 asm/atomic.h。大多数操作是直接内联汇编实现的,通过在汇编前面加 LOCK_PREFIX(通常是 lock)达到原子操作的效果。
部分其它操作前后也会加上 asm/barrier.h 定义的 barrier(),其原理是添加一条 lfence, mfence, sfence 指令。
4
a)
T1: 2
T2: 2
T3: 2
deadlock
T1->R3->T3->R1->T1
b)
T1: 2
T2: 1
T3: 2
T4: 2
cycle but no deadlock
完成顺序:T2 先完成,完成后 T1 和 T3 抢 R2,抢到者先执行,执行完毕后剩下一个人和 T4 并行。
故可能出现的排列有:2134,2143,2314,2341
5
| Allocated | Max | |
|---|---|---|
| $P_0$ | 010 | 753 |
| $P_1$ | 302 | 322 |
| $P_2$ | 302 | 902 |
| $P_3$ | 211 | 222 |
| $P_4$ | 002 | 433 |
| free | 230 |
requests: P_4 (3, 3, 0)
- Check that Request(3,3,0) \leq Available(3,3,2) \Rightarrow false
return fail
发表回复