题目
46.(8分)某进程中有3个并发执行的线程thread1、thread2和thread3,-|||-其伪代码如下所示。-|||-/复数的结构类型定义 thread l thread3-|||-typedef struct-|||-cnum w; cnum w:-|||-float a; =ad(x,y); .a=1;-|||-float b; ...... .b=1;-|||-{cnum; =add(2,mu );-|||-cnumx,y,z;/全局变量 =add(y,w);-|||-thread2-|||-/计算两个复数之和-|||-cnum add(cnump,cnumq) cnum w;-|||-=add(y,z);-|||-cnum s;-|||-.a=p.a+q.a;-|||-.b=p.b+q.b;-|||-return s;-|||-__-|||-请添加必要的信号量和P、V(或wait()、signal())操作,要求确保 () ()-|||-线程互斥访问临界资源,并且最大程度地并发执行。

题目解答
答案

解析
考查要点:本题主要考查多线程环境下对共享资源的互斥访问控制,要求通过信号量机制确保线程安全,同时尽可能提高并发执行效率。
解题核心思路:
- 识别共享变量:确定哪些变量被多个线程同时读写。根据伪代码,变量
y和z是共享资源。 - 分析访问模式:
- 变量
y:thread2和thread3均对其进行读写操作,需互斥访问。 - 变量
z:thread3对其进行写操作,需互斥访问。
- 变量
- 信号量设计:
y的互斥:使用两个信号量mutex_y1和mutex_y2,分别控制thread2和thread3对y的访问。z的互斥:使用信号量mutex_z控制对z的访问。
破题关键点:
- 互斥粒度:对共享变量的读写操作必须原子化,确保线程切换时不会导致数据不一致。
- 信号量分配:通过独立信号量区分不同线程对共享资源的访问,避免死锁并提高并发性。
信号量定义
semaphore mutex_y1 = 1; // 控制thread2对y的访问
semaphore mutex_y2 = 1; // 控制thread3对y的访问
semaphore mutex_z = 1; // 控制对z的访问
线程代码改造
thread2
cnum w;
wait(mutex_y1); // 独占y的访问权限
w = ad(x, y); // 读取y的值
signal(mutex_y1);
// ... 其他操作 ...
wait(mutex_y1); // 再次独占y的访问权限
y = ad(y, w); // 修改y的值
signal(mutex_y1);
thread3
cnum w;
wait(mutex_y2); // 独占y的访问权限
w = ad(y, z); // 读取y和z的值
signal(mutex_y2);
// ... 其他操作 ...
wait(mutex_y2); // 独占y的访问权限
y = ad(y, w); // 修改y的值
signal(mutex_y2);
// ... 对z的操作 ...
wait(mutex_z); // 独占z的访问权限
z = ad(y, w); // 修改z的值
signal(mutex_z);
关键说明:
- 互斥粒度:对
y的每次操作均通过信号量确保原子性,避免线程切换导致数据不一致。 - 并发优化:
thread2和thread3对y的访问通过独立信号量控制,允许部分并发,但严格禁止同时操作。