在互斥数据访问中有一种多读少写的情况。正对这么一种情形,我们也提出了​​读写锁​​的方案。但是呢,这个锁有些缺陷。什么缺陷呢?那就是,这个写锁需要在所有的读锁完成之后才能写。否则的话,写锁需要这么一直等下去。

那么,有没有什么办法能使得写操作快速一点进行呢?那就是顺序锁。

[cpp]​view plain​​​​copy​


  1. typedef struct _SEQUENCE_LOCK
  2. {
  3. unsigned int sequence;
  4. HANDLE hLock;

  5. }SEQUENCE_LOCK;


有了这么一个数据结构之后。那么读锁怎么开始呢,

[cpp]​view plain​​​​copy​


  1. unsigned int get_lock_begin(SEQUENCE_LOCK* hSeqLock)
  2. {
  3. assert(NULL != hSeqLock);

  4. return hSeqLock->sequence;
  5. }

  6. int get_lock_retry(SEQUENCE_LOCK* hSeqLock, unsigned int value)
  7. {
  8. unsigned int new_value;
  9. assert(NULL != hSeqLock);

  10. new_value = hSeqLock->sequence;
  11. return (new_value & 0x1) || (new_value ^ value);
  12. }


自然写锁也需要修改了,

[cpp]​view plain​​​​copy​


  1. void get_write_lock(SEQUENCE_LOCK* hSeqLock)
  2. {
  3. assert(NULL != hSeqLock);

  4. WaitForSingleObject(hSeqLock->hLock);
  5. hSeqLock->sequence ++;
  6. }

  7. void release_write_lock(SEQUENCE_LOCK* hSeqLock)
  8. {
  9. assert(NULL != hSeqLock);

  10. hSeqLock->sequence ++;
  11. ReleaseMutex(hSeqLock->hLock);
  12. }


如果应用呢,其实也不难,

[cpp]​view plain​​​​copy​


  1. void read_process(SEQUENCE_LOCK* hSeqLock)
  2. {
  3. unsigned int sequence;

  4. do{
  5. sequence = get_lock_begin(hSeqLock);
  6. /* read operation */
  7. }while(get_lock_retry(hSeqLock, sequence));
  8. }

  9. void write_process(SEQUENCCE_LOCK* hSeqLock)
  10. {
  11. get_write_lock(hSeqLock);
  12. /* write operation */
  13. release_write_lock(hSeqLock);
  14. }


总结:

    (1)读锁退出有两个条件,要么写操作正在进行呢,要么没有写锁

(2)写锁之间需要互斥操作

(3)互斥操作的数据不能是指针,否则有可能在访问的时候会造成异常,因为有可能边写边读

(4)顺序锁代替不了读写锁,因为读写锁可以保证所有的数据操作,而顺序锁不行