2017 操作系统 信号量 解答题
第 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 和 thread2thread2 和 thread3thread3 和 thread4给分
x不共享不共享不共享1 分
y同时读读写互斥读写互斥3 分
z不共享读写互斥不共享1 分

② 考生仅使用一个互斥信号量,互斥代码部分的得分最多给 2 分。③ 答案部分正确,酌情给分。