linux条件变量使用和与信号量的区别
今天在学习进程同步机制的时候看见一句话:
条件变量只能在管程中通过两个原语操作——wait原语和signal原语
于是发出了一个疑问:信号量机制和条件变量同步机制的区别在哪里?
一.简单介绍
1.条件变量同步机制
- 让进入管程却因资源不足而阻塞的进程暂时放弃管程控制权(开放管程),进入该条件变量的等待队列条件变量只能在管程中通过两个原语操作——wait原语和signal原语。
- 一个进程已进入管程但无法继续执行,便在相应的条件变量x上调用x.wait( ),将自己阻塞并移入x的等待队列中,放弃管程控制权(开放管程),另一进程可以通过对同一个条件变量执行x.signal( )来唤醒之前在x上等待的进程
- 条件变量仅起到维护等待队列的作用,不存在相关的值,也不能象信号量那样加减累计。
2.互斥锁
在编程中,引入了对象互斥锁的概念,来保证共享数据操作的完整性。每个对象都对应于一个可称为" 互斥锁" 的标记,这个标记用来保证在任一时刻,只能有一个线程访问该对象。
在Posix Thread中定义有一套专门用于线程同步的mutex()函数。
下面内容参考:https://www.shuzhiduo.com/A/n2d9WBDvJD/
二.条件变量的使用:(来自APUE,即UNIX环境高级编程)
#include <pthread.h>
struct msg {
struct msg *m_next;
/* ... more stuff here ... */
};
struct msg *workq;
pthread_cond_t qready = PTHREAD_COND_INITIALIZER;
pthread_mutex_t qlock = PTHREAD_MUTEX_INITIALIZER;
void process_msg(void)
{
struct msg *mp;
for (;;) {
pthread_mutex_lock(&qlock);
while (workq == NULL)
pthread_cond_wait(&qready, &qlock);
mp = workq;
workq = mp->m_next;
pthread_mutex_unlock(&qlock);
/* now process the message mp */
}
}
void enqueue_msg(struct msg *mp)
{
pthread_mutex_lock(&qlock);
mp->m_next = workq;
workq = mp;
pthread_mutex_unlock(&qlock);
pthread_cond_signal(&qready);
}
三.条件变量和信号量的区别:
(1)最大的区别应该是使用条件变量可以一次唤醒所有等待者,但信号量不行。
(2)信号量有一个表示状态的值,而条件变量是没有的,没有地方记录唤醒(发送信号)过多少次,也没有地方记录唤醒线程(wait返回)过多少次。从实现上来说一个信号量可以是用mutex + counter + condition variable实现的。因为信号量有一个状态,如果想精准的同步,那么信号量可能会有特殊的地方。信号量可以解决条件变量中存在的唤醒丢失问题。
(3)在Posix.1基本原理一文声称,有了互斥锁和条件变量还提供信号量的原因是:“本标准提供信号量的主要目的是提供一种进程间同步的方式,这些进程可能共享也可能不共享内存区。互斥锁和条件变量是作为线程间的同步机制说明的,这些线程总是共享(某个)内存区。”尽管信号量的意图在于进程间同步,互斥锁和条件变量的意图在于线程间同步,但是信号量也可用于线程间,互斥锁和条件变量也可用于进程间。信号量最有用的场景是用以指明可用资源的数量。
经典的一句话:
互斥量是信号量的一种特例,互斥量的本质是一把锁。A mutex is basically a lock that we set (lock) before accessing a shared resource and release (unlock) when we’re done
本文对比了Linux条件变量与信号量在进程同步中的应用,强调了条件变量的wait和signal原语,以及它们与信号量在唤醒机制、状态维护和用途上的差异。通过实例展示了如何在编程中使用条件变量,并指出信号量可以解决条件变量的一些局限性,如精确同步和资源计数。

6034

被折叠的 条评论
为什么被折叠?



