本来打算用一个形象的生活情况来比喻条件互斥的,但想了再想实在没有想到比较科学贴切的比喻.
那还是开门见山来说吧.
Condition Variable无论在C/C++还是C#,JAVA语言里,都会搭配一个Mutex来用.
我们知道Mutex的普通意义上是维持一个互斥变量,从而保证一个或一组操作的原子性.
同样,简单的说Mutex加在Condition Variable上也是为了保证它的原子性了.
Condition Variable,有条件的唤醒机制.最经典不过的就是生产--消息者模型了.
但有一个细节,消费者需要有"产品"才能继续它的消费行为,因此当消费者发现"产品"
被消费完了?它该怎么办?
没错,普通情况下它就会进入等待挂起状态.但这一状态什么时候才能结束?又是谁来告诉它
有"产品"可消费呢?没错,这个时候消费者就是在等待"有产品可消费"这一条件才会苏醒.
这个时候我们就能用到Condition Variable了.
上代码:#include <stdio.h>
#include <stdlib.h>
#include <pthread.h>
struct msg{
struct msg *next;
int num;
};
struct msg *head;
pthread_cond_t has_product;//Condition Variable
pthread_mutex_t lock = PTHREAD_MUTEX_INITIALIZER;//互斥锁初始化
void *consumer(void *p)
{
struct msg *mp;
for(;;){
pthread_mutex_lock(&lock);//保证生产与消费的互斥,消费者取得lock
while(head == NULL)
pthread_cond_wait(&has_product,&lock);
//其实while这一过程并不是必需的, pthread_cond_wait这一过程已经可以实现等待-执行可程了.但由于线程被唤醒的情况有多种,我们需要的是head!=NULL这种情况才会继续执行.而且pthread_cond_wait()这个方法还会有一个内在的执行过程,在pthread_cond_wait()这一过程中我们必需保证lock的持有,当线程刷新了等待队列之后,在被持起之前lock会被释放.
当另一个线程调用pthread_cond_signal()唤醒之前需要先把lock给释放了,因为调用pthread_cond_signal()后,消费进程需要重新通过pthread_cond_wait()这个方法获得lock,然后执行逻辑处理代码,最后消费进程释放lock.
mp = head;
head = mp->next;
pthread_mutex_unlock(&lock);//释放lock
printf("Consumer %d\n",mp->num);
free(mp);
sleep(rand()%5);
}
}
void *producer(void *p)
{
struct msg *mp;
for(;;){
mp = malloc(sizeof(struct msg));
mp->num = rand() % 1000+1;
printf("Produce %d\n",mp->num);
pthread_mutex_lock(&lock);//为保证操作的原子性获得lock
mp->next = head;
head = mp;
pthread_mutex_unlock(&lock);//释放lock
pthread_cond_signal(&has_product);//唤醒消费进程
sleep(rand()%5);
}
}
int main(int argc,char *argv[])
{
pthread_t pid,cid;
srand(time(NULL));
cid = pthread_create(&cid,NULL,consumer,NULL);
pid = pthread_create(&pid,NULL,producer,NULL);
sleep(5);
pthread_join(pid,NULL);
pthread_join(cid,NULL);
return 0;
}
上面文字解释是关键部份,主要是pthread_cond_wait()这一内在执行过程比较重要.
分享到:
相关推荐
它通常与互斥锁(Mutex)和锁_guard(Lock_Guard)一起使用,以实现线程安全的数据共享。 Condition_Variable 的主要成员函数 Condition_Variable 提供了多种成员函数来实现线程同步,包括: * wait():等待条件...
C++11中的各种mutex, lock对象,实际上都是对posix的mutex,condition的封装。不过里面也有很多细节值得学习。 std::mutex 先来看下std::mutex: 包增了一个pthread_mutex_t __m_,很简单,每个函数该干嘛...
std::condition_variable 的使用通常需要与 std::mutex 配合使用。 std::mutex 是一种互斥锁,用于保护共享资源的访问。 std::condition_variable 使用 std::unique_lock<std::mutex> 来等待,如果需要使用另外的 ...
当 std::condition_variable 对象的某个 wait 函数被调用的时候,它使用 std::unique_lock(通过 std::mutex) 来锁住当前线程。当前线程会一直被阻塞,直到另外一个线程在相同的 std::condition_variable 对象上调用...
#### 五、Mutex与共享池争用 Mutex机制主要用于保护Oracle数据库的共享池中的对象,避免多个进程同时访问同一个资源而导致的数据不一致问题。在高并发场景下,Mutex机制的有效性直接影响到系统的性能和稳定性。 - ...
通过一个标志位来处理的方式虽然可以实现效果,但是还不够安全,极有可能有多条线程同时操作一个全局变量,导致资源争夺问题,为了保证安全,可以在此基础上加上对应的锁来处理同步问题,比如加上互斥锁 mutex,就...
2. **Mutex的创建与销毁** 在C++中,我们可以使用`CreateMutex`函数来创建一个Mutex对象,创建时可以设置初始状态(是否已被占有)和命名(命名Mutex可以实现进程间同步)。当不再需要Mutex时,应使用`CloseHandle`...
在编程领域,特别是涉及到多线程或多进程编程时,互斥体(Mutex)是一个至关重要的概念。互斥体主要用于同步多个线程或进程对共享资源的访问,确保同一时间只有一个线程或进程能够访问该资源,从而避免数据冲突和竞...
当多个线程同时运行时,可能会引发数据竞争和不一致性问题,因此理解和掌握线程的同步与互斥至关重要。在给定的标题和描述中,我们关注的是如何利用Mutex和AutoResetEvent这两个类来解决这些问题。 Mutex(互斥锁)...
4. **超时与释放**:可以为`lock`方法设置超时时间,如果超过指定时间仍未获取到锁,函数会抛出异常。另外,记得在操作完成后释放锁,避免死锁: ```php $mutex->unlock($lock); ``` **三、Mutex的应用场景** ...
在Linux系统中,互斥锁(Mutex)是一种用于多线程同步的重要机制,它确保了在任何时刻只有一个线程能够访问特定的临界区。Mutex锁的使用是防止数据竞争和保证线程安全的关键手段。这个"mutex锁demo代码.rar"压缩包...
需求: 有三条线程,可以分别输出A、B、C字符,现想办法控制输出顺序,使得顺序为ABCABC......ABC[共10组],并且每条线程只能启动一次,不能多次启动。 需要3条线程输出不同的字符,分别为A、B、C,并且顺序要固定...
当一个线程获得了`Mutex`的所有权后,其他尝试获取该`Mutex`的线程将会被阻塞,直到当前持有者释放`Mutex`。这样就保证了在任何时刻只有一个线程能够执行特定的代码段,确保了数据的一致性。 在C#中,`Mutex`类位于...
在UCOS-II版本中,互斥信号量(Mutex)是实现任务间同步和资源保护的重要机制。本文件“create-mutex.zip”包含了关于在UCOS-II中创建和使用互斥信号量的源码及相关知识点。 1. **互斥信号量(Mutex)的概念**: ...
2. **线程创建与参数传递:** 主线程创建了两个子线程`t1`和`t2`,并分别传递了不同的文件名作为参数。 3. **互斥量操作:** 在`counter_words`函数中,每次读取字符前,先调用`pthread_mutex_lock()`锁定互斥量,...
当一个线程获取了Mutex后,其他试图获取该Mutex的线程将被阻塞,直到拥有Mutex的线程释放它。这样可以确保任何时候只有一个线程能访问受保护的代码或资源,从而避免并发问题。 在C++或.NET等支持线程编程的环境中,...
在这种情况下,可以结合使用`std::condition_variable`与Mutex。条件变量允许线程等待特定事件发生,而不会浪费CPU资源。当条件满足时,另一个线程可以通知等待线程继续执行。 5. **跨进程的Mutex** 跨进程的Mutex...
- **锁定与解锁**:Mutex的状态有两种,锁定和未锁定。当一个线程获取了Mutex,Mutex就会处于锁定状态,其他尝试获取的线程会被阻塞,直到拥有Mutex的线程释放它。 - **所有权**:Mutex一旦被一个线程获取,只有该...
这些函数可能与Windows API的对应函数类似,如`CreateMutex()`, `WaitForSingleObject()` 和 `ReleaseMutex()`。通过使用这些函数,开发者能够在MT5的多线程环境中确保数据的一致性和正确性。 在`mutex.mqh`中,...
在多线程编程中,互斥锁(Mutex)是一种重要的同步机制,用于保证共享资源在同一时刻只能被一个线程访问。本项目提供了在Linux和Windows系统下通用的互斥锁Mutex封装,实现了跨平台的兼容性,使得开发者无需关心底层...