Open supergem3000 opened 7 months ago
9. 并发控制:同步 (1) (jyywiki.cn) 同步问题 同步:两个或两个以上随时间变化的量在变化过程中保持一定的相对关系。 线程同步:在某个时间点共同达到互相已知的状态。
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++
99%的实际并发问题都可以用生产者-消费者解决。
void Tproduce() { while (1) printf("("); } void Tconsume() { while (1) printf(")"); }
在printf前后增加代码,使得打印的括号序列满足:
printf
TProduce
Tconsume
同步问题分析:线程同步由条件不成立等待和同步条件达成继续构成。 线程join:
nexit == T
nexit++
CAN_PRODUCE (count < n)
count--
CAN_CONSUME (count > 0)
count++
条件变量:理想与实现之间的折衷。 一把互斥锁+一个“条件变量”+手工唤醒。
wait(cv, mutex)
mutex
wait
lock(mutex)
signal/notify(cv)
broadcast/notifyAll(cv)
课程网站示例代码,if的实现错误原因:等待被唤醒时,也不一定满足条件。
正确的使用方式 需要等待条件满足时:
mutex_lock(&mutex); while (!COND) { wait(&cv, &mutex); } assert(COND); // 互斥锁保证条件成立 mutex_unlock(&mutex);
任何改动使其他线程可能被满足时:
mutex_lock(&mutex); // 任何可能使条件满足的代码 broadcast(&cv); mutex_unlock(&mutex);
生产者-消费者问题
条件变量:理想与实现之间的折衷。 一把互斥锁+一个“条件变量”+手工唤醒。
wait(cv, mutex)
mutex
wait
释放mutex
,进入睡眠状态lock(mutex)
signal/notify(cv)
broadcast/notifyAll(cv)
正确的使用方式 需要等待条件满足时:
任何改动使其他线程可能被满足时: