`
M_ittrue
  • 浏览: 76989 次
  • 性别: Icon_minigender_1
  • 来自: 长沙
社区版块
存档分类
最新评论

Condition Variable与Mutex搭配的前因后果

 
阅读更多

本来打算用一个形象的生活情况来比喻条件互斥的,但想了再想实在没有想到比较科学贴切的比喻.

那还是开门见山来说吧.

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()这一内在执行过程比较重要.

分享到:
评论

相关推荐

    condition_variable源码以及详细分析.docx

    它通常与互斥锁(Mutex)和锁_guard(Lock_Guard)一起使用,以实现线程安全的数据共享。 Condition_Variable 的主要成员函数 Condition_Variable 提供了多种成员函数来实现线程同步,包括: * wait():等待条件...

    C++11中的mutex, lock, condition variable实现分析

    C++11中的各种mutex, lock对象,实际上都是对posix的mutex,condition的封装。不过里面也有很多细节值得学习。  std::mutex  先来看下std::mutex:  包增了一个pthread_mutex_t __m_,很简单,每个函数该干嘛...

    C++11 并发指南五(stdcondition_variable 详解).docx

    std::condition_variable 的使用通常需要与 std::mutex 配合使用。 std::mutex 是一种互斥锁,用于保护共享资源的访问。 std::condition_variable 使用 std::unique_lock&lt;std::mutex&gt; 来等待,如果需要使用另外的 ...

    C++基于消息队列的多线程实现示例代码

    当 std::condition_variable 对象的某个 wait 函数被调用的时候,它使用 std::unique_lock(通过 std::mutex) 来锁住当前线程。当前线程会一直被阻塞,直到另外一个线程在相同的 std::condition_variable 对象上调用...

    图文并茂Mutex性能问题解析

    #### 五、Mutex与共享池争用 Mutex机制主要用于保护Oracle数据库的共享池中的对象,避免多个进程同时访问同一个资源而导致的数据不一致问题。在高并发场景下,Mutex机制的有效性直接影响到系统的性能和稳定性。 - ...

    <一>、C++实现多线程的同步处理:控制ABC的输出顺序,输出10组,mutex+condition-variable源码示例

    通过一个标志位来处理的方式虽然可以实现效果,但是还不够安全,极有可能有多条线程同时操作一个全局变量,导致资源争夺问题,为了保证安全,可以在此基础上加上对应的锁来处理同步问题,比如加上互斥锁 mutex,就...

    mutexs application.rar_Mutex_mutex 多线程

    2. **Mutex的创建与销毁** 在C++中,我们可以使用`CreateMutex`函数来创建一个Mutex对象,创建时可以设置初始状态(是否已被占有)和命名(命名Mutex可以实现进程间同步)。当不再需要Mutex时,应使用`CloseHandle`...

    删除程序的 mutex 互斥句柄

    在编程领域,特别是涉及到多线程或多进程编程时,互斥体(Mutex)是一个至关重要的概念。互斥体主要用于同步多个线程或进程对共享资源的访问,确保同一时间只有一个线程或进程能够访问该资源,从而避免数据冲突和竞...

    C# 多线程的同步与互斥(使用Mutex和Event)

    当多个线程同时运行时,可能会引发数据竞争和不一致性问题,因此理解和掌握线程的同步与互斥至关重要。在给定的标题和描述中,我们关注的是如何利用Mutex和AutoResetEvent这两个类来解决这些问题。 Mutex(互斥锁)...

    Laravel开发-laravel-mutex

    4. **超时与释放**:可以为`lock`方法设置超时时间,如果超过指定时间仍未获取到锁,函数会抛出异常。另外,记得在操作完成后释放锁,避免死锁: ```php $mutex-&gt;unlock($lock); ``` **三、Mutex的应用场景** ...

    mutex锁demo代码.rar

    在Linux系统中,互斥锁(Mutex)是一种用于多线程同步的重要机制,它确保了在任何时刻只有一个线程能够访问特定的临界区。Mutex锁的使用是防止数据竞争和保证线程安全的关键手段。这个"mutex锁demo代码.rar"压缩包...

    <二>、C++实现多线程的同步处理:控制ABC的输出顺序,输出10组,mutex+condition-variable源码示例

    需求: 有三条线程,可以分别输出A、B、C字符,现想办法控制输出顺序,使得顺序为ABCABC......ABC[共10组],并且每条线程只能启动一次,不能多次启动。 需要3条线程输出不同的字符,分别为A、B、C,并且顺序要固定...

    C# 使用Mutex实现多线程同步实例

    当一个线程获得了`Mutex`的所有权后,其他尝试获取该`Mutex`的线程将会被阻塞,直到当前持有者释放`Mutex`。这样就保证了在任何时刻只有一个线程能够执行特定的代码段,确保了数据的一致性。 在C#中,`Mutex`类位于...

    create-mutex.zip_Mutex_mutex in ucos_uCOS mutex_ucos mutex

    在UCOS-II版本中,互斥信号量(Mutex)是实现任务间同步和资源保护的重要机制。本文件“create-mutex.zip”包含了关于在UCOS-II中创建和使用互斥信号量的源码及相关知识点。 1. **互斥信号量(Mutex)的概念**: ...

    linux上互斥线程Mutex的代码及解释

    2. **线程创建与参数传递:** 主线程创建了两个子线程`t1`和`t2`,并分别传递了不同的文件名作为参数。 3. **互斥量操作:** 在`counter_words`函数中,每次读取字符前,先调用`pthread_mutex_lock()`锁定互斥量,...

    利用Mutex互斥变量实现线程同步机制

    当一个线程获取了Mutex后,其他试图获取该Mutex的线程将被阻塞,直到拥有Mutex的线程释放它。这样可以确保任何时候只有一个线程能访问受保护的代码或资源,从而避免并发问题。 在C++或.NET等支持线程编程的环境中,...

    使用互斥对象(Mutex)实现不同进程间线程同步

    在这种情况下,可以结合使用`std::condition_variable`与Mutex。条件变量允许线程等待特定事件发生,而不会浪费CPU资源。当条件满足时,另一个线程可以通知等待线程继续执行。 5. **跨进程的Mutex** 跨进程的Mutex...

    利用Mutex标记限制程序重复运行

    - **锁定与解锁**:Mutex的状态有两种,锁定和未锁定。当一个线程获取了Mutex,Mutex就会处于锁定状态,其他尝试获取的线程会被阻塞,直到拥有Mutex的线程释放它。 - **所有权**:Mutex一旦被一个线程获取,只有该...

    Mutex - WinAPI - MetaTrader 5程序库.zip

    这些函数可能与Windows API的对应函数类似,如`CreateMutex()`, `WaitForSingleObject()` 和 `ReleaseMutex()`。通过使用这些函数,开发者能够在MT5的多线程环境中确保数据的一致性和正确性。 在`mutex.mqh`中,...

    linux和win32下通用的互斥锁Mutex封装

    在多线程编程中,互斥锁(Mutex)是一种重要的同步机制,用于保证共享资源在同一时刻只能被一个线程访问。本项目提供了在Linux和Windows系统下通用的互斥锁Mutex封装,实现了跨平台的兼容性,使得开发者无需关心底层...

Global site tag (gtag.js) - Google Analytics