线程同步时会遇到互斥量和条件变量配合使用的情况,下面看一下C++版的。
test.h
#include <pthread.h>
#include <iostream>
class T_Mutex
{
public:
T_Mutex() { pthread_mutex_init(&mutex_, NULL); }
~T_Mutex() { pthread_mutex_destroy(&mutex_); }
void Lock() { pthread_mutex_lock(&mutex_); }
void Unlock() { pthread_mutex_unlock(&mutex_); }
pthread_mutex_t *getMutex() { return &mutex_; }
private:
pthread_mutex_t mutex_;
};
class T_Condition {
public:
T_Condition(pthread_mutex_t *mutex) : _mutex(mutex) {
pthread_cond_init(&_cond, NULL);
}
~T_Condition() {
pthread_cond_destroy(&_cond);
}
int Wait() { pthread_cond_wait(&_cond, _mutex); }
void Signal() { pthread_cond_signal(&_cond); }
void Broadcast() { pthread_cond_broadcast(&_cond); }
private:
pthread_cond_t _cond;
pthread_mutex_t *_mutex;
};
class T_MutexCond : public T_Mutex, public T_Condition {
public:
explicit T_MutexCond(void) : T_Mutex(), T_Condition(getMutex()) {}
};
class ScopedLock {
public:
explicit ScopedLock(pthread_mutex_t *mutex) : m_mutex(mutex) { //传入mutex
pthread_mutex_lock(m_mutex);
}
explicit ScopedLock(T_Mutex *mutex) : m_mutex(mutex->getMutex()) { //传入T_Mutex
pthread_mutex_lock(m_mutex);
}
~ScopedLock() {
pthread_mutex_unlock(m_mutex);
}
private:
ScopedLock();
pthread_mutex_t *m_mutex;
};
将互斥量和条件变量对应的API封装起来,ScopedLock的构造自动加锁,析构自动释放锁很便捷。
test.cpp
#include <iostream>
#include <pthread.h>
#include <unistd.h>
#include <stdio.h>
#include "test.h"
T_MutexCond m_cond;
unsigned count = 0;
void *func1(void *arg)
{
ScopedLock lock(&m_cond);
while(count == 0)
{
printf("func1 Wait\n");
m_cond.Wait();
}
count = count + 1;
printf("func1_count =%d\n",count);
}
void *func2(void *arg)
{
ScopedLock lock(&m_cond);
if(count == 0)
{
printf("func2 Signal\n");
m_cond.Signal();
}
count = count + 1;
printf("func2_count =%d\n",count);
}
int main(void)
{
pthread_t tid1, tid2;
pthread_create(&tid1, NULL, func1, NULL);
sleep(5);
pthread_create(&tid2, NULL, func2, NULL);
pthread_join(tid1, NULL);
pthread_join(tid2, NULL);
return 0;
}
运行结果为:func1 Wait
func2 Signal
func2_count =1
func1_count =2
pthread_cond_wait(&_cond, _mutex)内部有释放互斥锁的操作,不然func2不可能获取到互斥锁。ScopedLock避免了C语言的手动释放锁的操作。