先来看互斥Mutex
class Mutex {
enum { PRIVATE = 0, SHARED = 1};
Mutex();
Mutex(const char* name);
Mutex(int type, const char* name = NULL);
~Mutex();
status_t lock();
void unlock();
status_t tryLock();
}
再看Autolock
class Autolock {
public:
inline Autolock(Mutex& mutex) : mLock(mutex) { mLock.lock(); }
inline Autolock(Mutex&* mutex) : mLock(*mutex) {mLock.lock();}
inline ~Autolock() { mLock.unlock(); }
private:
Mutex& mLock;
}
Condition类和java中的wait,notify功能类似,只是java封装在了object中了。
Condition在调wait的时候,必须在锁的中间。而且wait的时候和java一样也会将所持的锁释放。
class Condition {
public:
enum {
PRIVATE = 0,
SHARED = 1
};
Condition();
Condition(int type);//如果type是SHARED,表示支持跨进程的条件同步
~Condition();
//线程B和C等待事件,wait这个名字是不是很形象呢?
status_t wait(Mutex& mutex);
//线程B和C的超时等待,B和C可以指定等待时间,当超过这个时间,条件却还不满足,则退出等待。
status_t waitRelative(Mutex& mutex, nsecs_t reltime);
//触发者A用来通知条件已经满足,但是B和C只有一个会被唤醒。
void signal();
//触发者A用来通知条件已经满足,所有等待者都会被唤醒。
void broadcast();
下面看一个例子:
class Barrier
{
public:
inline Barrier() : state(CLOSED) { }//state就是所谓的“条件”
inline ~Barrier() { }
void open() {
Mutex::Autolock _l(lock);
state = OPENED;
cv.broadcast();
}
void close() {
Mutex::Autolock _l(lock);
state = CLOSED;
}
void wait() const {
Mutex::Autolock _l(lock);//临时对象_l,用lock来构造,在AutoLock的构造函数里已给lock加锁(调用lock()函数)——该wait()函数执行完毕,会自动释放lock(这个场景会使得其他线程再次修改state,产生不安全因素。不过由于Barrier的使用场景的特殊性,其用在线程初始化时,故OK。)
while (state == CLOSED) {//while语句:不断轮询,直到state==OPENED
cv.wait(lock);
}
}
private:
enum { OPENED, CLOSED };
mutable Mutex lock;//持有一个互斥锁
mutable Condition cv;//持有一个条件变量
volatile int state;//每次都从内存更新的“条件”
};