|
WINDOWS下通过事件对象和临界区实现“读写锁”
- void rwlock::lock(int _direct)
- {
- EnterCriticalSection(&start_lock);
- while (count > 0 && (direct != _direct || _direct == LOCK_WRITE))
- {
- WaitForSingleObject(finish_event, INFINITE);
- }
- direct = _direct;
- InterlockedIncrement(&count);
- LeaveCriticalSection(&start_lock);
- }
- void rwlock::unlock(int _direct)
- {
- InterlockedDecrement(&count);
- SetEvent(finish_event);
- }
复制代码 其中direct为当前进行中的读写状态
1、当第一次有READ请求进入的时候,由于count计数为0,将direct标记为READ并增加count计数后就直接跳出锁执行下面的代码。
当前状态:direct==READ,count==1
2、当第二次有WRITE请求进入的时候,由于count计数为1,direct不为READ,条件成立后进入事件等待。
当前状态:direct==READ,count==1
3、当第三次有READ请求进入的时候,由于direct等于READ,所以直接增加count的计数后跳出锁执行下面的代码。
当前状态:direct==READ,count==2
4、当执行一次unlock时,count计数减去1,给EVENT一个信号量,让队列中的某一个线程继续执行,此时count为1并且队列中的请求为WRITE(因为direct为READ,所以所有的READ请求都被放行了),所以继续等待下次EVENT的触发,SetEvent的第二个参数为FALSE,所以信号是自动重置的。
当前状态:direct==READ,count==1
5、当再次执行unlock时,count==0,此时WRITE请求被放行,并将direct设置成WRITE,count为1,然后跳出锁执行写操作。
当前状态:direct==WRITE,count==1
6、 此时如果有READ请求的话,由于count>0,并且direct!=READ,,所以READ请求进入等待队列。
当前状态:direct==WRITE,count==1
7、 如果有WRITE请求的话,由于count>0,并且_direct==LOCK_WRITE,所以也进入对待队列。
当前状态:direct==WRITE,count==1 |
|