第 46 题
某进程中有 3 个并发执行的线程 thread1、thread2、thread3,其伪代码如下所示。
//复数的结构类型定义
typedef struct
{
float a;
float b;
} cnum;
//全局变量
cnum x,y,z;
//计算两个复数之和
cnum add(cnum p,cnum q)
{
cnum s;
s.a=p.a+q.a;
s.b=p.b+q.b;
return s;
}
thread1
{
cnum w;
w=add(x,y);
...
}
thread2
{
cnum w;
w=add(y,z);
...
}
thread3
{
cnum w;
w.a=1;
w.b=2;
z=add(z,w);
y=add(y,w);
...
}
请添加必要的信号量和 P、V(或 wait()、signal())操作,要求确保线程互斥访问临界资源,并且最大程度地并发执行。
[tag_link]
先找出线程对在各个变量上的互斥、并发关系。如果是一读一写或两个都是写,那么这就是互斥关系。每一个互斥关系都需要一个信号量进行调节。
// 冲突:
// t1 和 t3 关于 y 有读写冲突
// t2 和 t3 关于 y, z 都有读写冲突
// 解决 t1 和 t3 关于 y 读写冲突
semaphore y_mutex1 = 1;
semaphore y_mutex2 = 1;
semaphore z_mutex = 1;
// 全局变量 x y z
cnum x, y, z;
thread1()
{
cnum w;
// 读 x, y
P(y_mutex1);
w = add(x, y);
V(y_mutex1);
// ...
}
thread2()
{
cnum w;
// 读 y, z
P(z_mutex);
P(y_mutex2);
w = add(y, z);
V(y_mutex2);
V(z_mutex);
// ...
}
thread3()
{
cnum w;
w.a = 1;
w.b = 1;
// 写 z
P(z_mutex);
z = add(z, w);
V(z_mutex);
// 写 y
P(y_mutex1);
P(y_mutex2);
y = add(y, w);
V(y_mutex2);
V(y_mutex1);
// ...
}
【评分标准】① 各线程与变量之间的互斥、并发情况及相应评分见下表。
| 变量/线程对 | thread1 和 thread2 | thread2 和 thread3 | thread3 和 thread4 | 给分 |
|---|---|---|---|---|
| x | 不共享 | 不共享 | 不共享 | 1 分 |
| y | 同时读 | 读写互斥 | 读写互斥 | 3 分 |
| z | 不共享 | 读写互斥 | 不共享 | 1 分 |
② 考生仅使用一个互斥信号量,互斥代码部分的得分最多给 2 分。③ 答案部分正确,酌情给分。