当前位置:软件学习 > 其它软件 >>

多线程的那点儿事(之读写锁)

 

【 声明:版权所有,欢迎转载,请勿用于商业用途。  联系信箱:feixiaoxing @163.com】

 

 

    在编写多线程的时候,有一种情况是十分常见的。那就是,有些公共数据修改的机会比较少。相比较改写,它们读的机会反而高的多。通常而言,在读的过程中,往往伴随着查找的操作,中间耗时很长。给这种代码段加锁,会极大地降低我们程序的效率。那么有没有一种方法,可以专门处理这种多读少写的情况呢?

    有,那就是读写锁。

 

 

    (1)首先,我们定义一下基本的数据结构。

 

 

typedef struct _RWLock 

    int count; 

    int state; 

    HANDLE hRead; 

    HANDLE hWrite; 

}RWLock;    

typedef struct _RWLock

{

    int count;

    int state;

    HANDLE hRead;

    HANDLE hWrite;

}RWLock;       同时,为了判断当前的锁是处于读状态,还是写状态,我们要定义一个枚举量,

typedef enum 

    STATE_EMPTY = 0, 

    STATE_READ, 

    STATE_WRITE 

}; 

typedef enum

{

    STATE_EMPTY = 0,

    STATE_READ,

    STATE_WRITE

};    (2)初始化数据结构

 

RWLock* create_read_write_lock(HANDLE hRead, HANDLE hWrite) 

    RWLock* pRwLock = NULL; 

 

    assert(NULL != hRead && NULL != hWrite); 

    pRwLock = (RWLock*)malloc(sizeof(RWLock)); 

   

    pRwLock->hRead = hRead; 

    pRwLock->hWrite = hWrite; 

    pRwLock->count = 0; 

    pRwLock->state = STATE_EMPTY; 

    return pRwLock; 

RWLock* create_read_write_lock(HANDLE hRead, HANDLE hWrite)

{

    RWLock* pRwLock = NULL;

 

    assert(NULL != hRead && NULL != hWrite);

    pRwLock = (RWLock*)malloc(sizeof(RWLock));

 

    pRwLock->hRead = hRead;

    pRwLock->hWrite = hWrite;

    pRwLock->count = 0;

    pRwLock->state = STATE_EMPTY;

    return pRwLock;

}    (3)获取读锁

 

void read_lock(RWLock* pRwLock) 

    assert(NULL != pRwLock); 

     

    WaitForSingleObject(pRwLock->hRead, INFINITE); 

    pRwLock->counnt ++; 

    if(1 == pRwLock->count){ 

        WaitForSingleObject(pRwLock->hWrite, INFINITE); 

        pRwLock->state = STATE_READ; 

    } 

    ReleaseMutex(pRwLock->hRead); 

void read_lock(RWLock* pRwLock)

{

    assert(NULL != pRwLock);

   

    WaitForSingleObject(pRwLock->hRead, INFINITE);

    pRwLock->counnt ++;

    if(1 == pRwLock->count){

        WaitForSingleObject(pRwLock->hWrite, INFINITE);

        pRwLock->state = STATE_READ;

    }

    ReleaseMutex(pRwLock->hRead);

}    (4)获取写锁

void write_lock(RWLock* pRwLock) 

    assert(NULL != pRwLock); 

 

    WaitForSingleObject(pRwLock->hWrite, INFINITE); 

    pRwLock->state = STATE_WRITE; 

void write_lock(RWLock* pRwLock)

{

    assert(NULL != pRwLock);

 

    WaitForSingleObject(pRwLock->hWrite, INFINITE);

    pRwLock->state = STATE_WRITE;

}    (5)释放读写锁

void read_write_unlock(RWLock* pRwLock) 

    assert(NULL != pRwLock); 

 

    if(STATE_READ == pRwLock->state){ 

        WaitForSingleObject(pRwLock->hRead, INFINITE); 

        pRwLock->count --; 

        if(0 == pRwLock->count){ 

            pRwLock->state = STATE_EMPTY; 

            ReleaseMutex(pRwLock->hWrite); 

        } 

        ReleaseMutex(pRwLock->hRead); 

    }else{ 

        pRwLock->state = STATE_EMPTY; 

        ReleaseMutex(pRwLock->hWrite); 

    } 

     

    return; 

void read_write_unlock(RWLock* pRwLock)

{

    assert(NULL != pRwLock);

 

    if(STATE_READ == pRwLock->state){

        WaitForSingleObject(pRwLock->hRead, INFINITE);

        pRwLock->count --;

        if(0 == pRwLock->count){

            pRwLock->state = STATE_EMPTY;

            ReleaseMutex(pRwLock->hWrite);

        }

        ReleaseMutex(pRwLock->hRead);

    }else{

        pRwLock->state = STATE_EMPTY;

        ReleaseMutex(pRwLock->hWrite);

    }

   

    return;

}

文章总结:

    (1)读写锁的优势只有在多读少写、代码段运行时间长这两个条件下才会效率达到最大化;

    (2)任何公共数据的修改都必须在锁里面完成;

    (3)读写锁有自己的应用场所,选择合适的应用环境十分重要;

    (4)编写读写锁很容易出错,朋友们应该多加练习;

    (5)读锁和写锁一定要分开使用,否则达不到效果

补充:软件开发 , 其他 ,
CopyRight © 2012 站长网 编程知识问答 www.zzzyk.com All Rights Reserved
部份技术文章来自网络,