gem-universe / blog

0 stars 0 forks source link

[操作系统]9. 并发控制-同步(生产者-消费者与条件变量) #9

Open supergem3000 opened 7 months ago

supergem3000 commented 7 months ago

9. 并发控制:同步 (1) (jyywiki.cn)

同步问题

同步:两个或两个以上随时间变化的量在变化过程中保持一定的相对关系。 线程同步:在某个时间点共同达到互相已知的状态。

生产者-消费者问题

99%的实际并发问题都可以用生产者-消费者解决。

void Tproduce() { while (1) printf("("); }
void Tconsume() { while (1) printf(")"); }

printf前后增加代码,使得打印的括号序列满足:

  • 一定是某个合法括号序列的前缀
  • 括号嵌套的深度不超过n 生产者-消费者问题中的同步
  • TProduce:等到有空位时才能打印左括号(生产资源,放入队列)
  • Tconsume:等到有多余的左括号时才能打印右括号(从队列取出资源) 如何实现?可以简单粗暴直接用互斥锁实现。问题:开销大。

    条件变量

    同步问题分析:线程同步由条件不成立等待同步条件达成继续构成。 线程join:

  • Tmain同步条件:nexit == T 退出的线程数量达到总数
  • Tmain达成同步:最后一个线程退出nexit++ 生产者/消费者问题:
  • Tproduce同步条件:CAN_PRODUCE (count < n)
  • Tproduce达成同步:Tconsume count--
  • Tconsume同步条件:CAN_CONSUME (count > 0)
  • Tconsume达成同步:Tproduce count++

条件变量:理想与实现之间的折衷。 一把互斥锁+一个“条件变量”+手工唤醒。

正确的使用方式 需要等待条件满足时:

mutex_lock(&mutex);
while (!COND) {
  wait(&cv, &mutex);
}
assert(COND); // 互斥锁保证条件成立
mutex_unlock(&mutex);

任何改动使其他线程可能被满足时:

mutex_lock(&mutex);
// 任何可能使条件满足的代码
broadcast(&cv);
mutex_unlock(&mutex);