ACE定义了四个宏:ACE_WRITE_GUARD、ACE_WRITE_GUARD_RETURN、ACE_READ_GUARD、ACE_READ_GUARD_RETURN。这四个宏的目的是为了实现高效的读写机制。其实就是定义两种对象:ACE_Read_Guard和ACE_Write_Guard。这两个类的意义在于在构造的时候,自动对应类型的锁,在析构的时候释放。为了保证高效率,如何构造读写锁就比较重要。比如说,使用ACE_Thread_Mutex的时候,虽然它也支持读写锁的接口,但是这并不是最好的选择,因为对于它来说,读写的加锁方式是完全一样的。所以说,如果用ACE_Thread_Mutex来实现读写锁的话,和普通加锁是没有区别的。
在这里,先还想讨论一下,为什么要加读写锁,读写锁和互斥锁相比的优势又是在什么地方。在看实现的时候,读写锁内部是存在互斥锁的,这些互斥锁为了保护结构的修改。读写锁的意义在于,如果操作是个费时操作,那么读写锁的优势就能够体现了。优势在于读的同时不影响别的读操作。但是如果操作是不费时的,读写锁就没有意义了。
那么再说一下读写锁的实现,对于进程范围来说是使用ACE_RW_Thread_Mutex是比较好的选择。对于Win32来说,使用的是WaitForSingleObject,而对于Posix来说,本来就有读写锁的设置。那么仅仅对win32来说,读写到底有什么不同。看看实现的代码,
写锁:while (rw->ref_count_ != 0)
{
rw->num_waiting_writers_++;
if (ACE_OS::cond_wait (&rw->waiting_writers_, &rw->lock_) == -1)
{
result = -2; // -2 means we need to release the mutex.
break;
}
rw->num_waiting_writers_--;
}
读锁:while (rw->ref_count_ < 0 || rw->num_waiting_writers_ > 0)
{
rw->num_waiting_readers_++;
if (ACE_OS::cond_wait (&rw->waiting_readers_, &rw->lock_) == -1)
{
result = -2; // -2 means that we need to release the mutex.
break;
}
rw->num_waiting_readers_--;
}
这就是实现的Win32的代码,也就是说,对于读来说,只要没有用户正在写,就可以跳出循环;但对于写用户来说,必须要没有用户持有锁才可以跳出循环,无论是读用户还是写用户。对于Posix来说就简单了,直接调用系统提供的读写机制就可以。