天天看點

linux下使用讀寫鎖

    在多線程程式中,有一種讀寫者的問題,即對某些資源的通路,存在兩種可能的情況,一種是通路必須排他的,稱為寫操作;另外一種通路是可共享的,稱為讀操作。

    處理讀寫着問題的兩種常見政策是:強讀者同步和強寫者同步。在強讀者同步過程中,總是給讀者優先權,隻要寫着目前沒有進行寫操作,讀者就可以獲得通路權。在強寫者同步過程中,通常将優先權先交給寫者,而将讀者延遲到所有等待的或者活動的寫者都完成為止。簡單的說:

    (1)可以同時存在多個讀操作

    (2)寫必須互斥(隻允許一個寫操作,不能讀寫操作同時進行)

    (3)寫操作優先于讀操作,(一旦有寫操作,後續的讀操作必須等待,喚醒時有限考慮寫操作)

    下面是兩種讀寫鎖的使用示例.

    一:POSIX 下的rw_lock

點選(此處)折疊或打開

#include pthread.h>

#include cstdlib>

#include ctime>

#include iostream>

using namespace std;

static int count = 0;

class Test

{

private :

    pthread_rwlock_t rwlock;

    static void* shared_task_handler(void* arg)

    {

        Test* testptr = static_castTest*>(arg);

        pthread_rwlock_rdlock(&testptr->rwlock);

        //    do the shared task here

        cout "read---count = " count endl;

        if (pthread_rwlock_unlock(&testptr->rwlock) )

        {

            cout "read unlock error " endl;

        }

        return NULL;

    }

    static void * exclusive_task_handler(void * arg)

        pthread_rwlock_wrlock(&testptr->rwlock);

        //do the exclusive task here

        ++count;

        cout "write--count = " count endl;

            cout "write unlock error " endl;

public :

    typedef void* (*ThreadFunc) (void*);

    void start()

        srand(time(NULL));

        if( pthread_rwlock_init(&rwlock,NULL) )

            cout "rwlock init error " endl;

        const int THREADS_NO = rand()%100;

        pthread_t* threads = new pthread_t[THREADS_NO];

        for(int i = 0; i THREADS_NO; ++i)

            ThreadFunc tmpfunc = rand() % 2 ? shared_task_handler : exclusive_task_handler;

            if (pthread_create(threads+i,NULL,tmpfunc,this))

            {

                cerr "pthread_create fails" endl;

                exit(1);

            }

        rwlock

        for(int i=0; iTHREADS_NO; i++)

            pthread_join(threads[i],NULL);

        delete[] threads;

};

int main()

    Test tmptest;

    tmptest.start();

}

output:

lee@lee-desktop:~/share$ ./posix_read_write_lock

write--count = 1

write--count = 2

write--count = 3

read---count = 3

write--count = 4

read---count = 4

write--count = 5

write--count = 6

read---count = 6

write--count = 7

write--count = 8

read---count = 8

write--count = 9

write--count = 10

read---count = 10

write--count = 11

write--count = 12

write--count = 13

write--count = 14

write--count = 15

read---count = 15

    二:利用pthread_cond_*  &  pthread_mutex_* 實作rw_lock

class RWLock

    pthread_mutex_t cnt_mutex;

    pthread_cond_t rw_cond;

    int rd_cnt, wr_cnt;

    RWLock(const RWLock&);

    RWLock& operator= (const RWLock&);

    RWLock(): rd_cnt(0),wr_cnt(0)

        pthread_mutex_init(&cnt_mutex, NULL);

        pthread_cond_init(&rw_cond, NULL);

    void get_shared_lock()

        pthread_mutex_lock(&cnt_mutex);

        while (wr_cnt >0)

            pthread_cond_wait(&rw_cond,&cnt_mutex);

        rd_cnt++;

        pthread_mutex_unlock(&cnt_mutex);

    void release_shared_lock()

        rd_cnt--;

        if (0 == rd_cnt)

            pthread_cond_signal(&rw_cond);

    void get_exclusive_lock()

        while (rd_cnt + wr_cnt>0)

        wr_cnt++;

    void release_exclusive_lock()

        wr_cnt--;

        pthread_cond_broadcast(&rw_cond);

    ~RWLock()

        pthread_mutex_destroy(&cnt_mutex);

        pthread_cond_destroy(&rw_cond);

    RWLock lock;

        testptr->lock.get_shared_lock();

        testptr->lock.release_shared_lock();

        testptr->lock.get_exclusive_lock();

        testptr->lock.release_exclusive_lock();

  output:

lee@lee-desktop:~/share$ ./read_write_lock

read---count = 0

read---count = 1

read---count = 11

read---count = 13

write--count = 16

write--count = 17

write--count = 18

write--count = 19

read---count = 19

write--count = 20

read---count = 20

write--count = 21

read---count = 21

write--count = 22

read---count = 22

write--count = 23

read---count = 23

write--count = 24

read---count = 24

write--count = 25

write--count = 26

write--count = 27

write--count = 28

read---count = 28

write--count = 29

write--count = 30

read---count = 30

write--count = 31

read---count = 31

write--count = 32

read---count = 32

write--count = 33

read---count = 33

write--count = 34

write--count = 35

    參考:

        http://www.cppblog.com/bigsml/archive/2006/09/07/12137.html

繼續閱讀