Linux并发与同步专题 (5) 读写锁

    在多线程程序中,有一种读写者的问题,即对某些资源的访问,存在两种可能的情况,一种是访问必须排他的,称为写操作;另外一种访问是可共享的,称为读操作。

    处理读写着问题的两种常见策略是:强读者同步和强写者同步在强读者同步过程中,总是给读者优先权,只要写着当前没有进行写操作,读者就可以获得访问权。在强写者同步过程中,通常将优先权先交给写者,而将读者延迟到所有等待的或者活动的写者都完成为止简单的说:

    (1)可以同时存在多个读操作

    (2)写必须互斥(只允许一个写操作,不能读写操作同时进行)

    (3)写操作优先于读操作,(一旦有写操作,后续的读操作必须等待,唤醒时有限考虑写操作)

    下面是两种读写锁的使用示例。
    一:POSIX下的rw_lock

code:

#include < pthread 。h >
#include < cstdlib >
#include < ctime >
#include < iostream >
using namespace std ;

static int count = 0 ;
课堂考试
{
私人的 : 
    pthread_rwlock_t rwlock ;
    
    static void * shared_task_handler ( void * arg )
    {
        Test * testptr = static_cast < Test * > ( arg );
        pthread_rwlock_rdlock (& testptr - > rwlock );
        / /     做共享在这里的任务
        COUT < < “读---计数=” < <计数< < ENDL ;
        if ( pthread_rwlock_unlock (& testptr - > rwlock ) )
        {
            COUT < < “读解锁错误” < < ENDL ;
        }
        返回NULL ;
    }
    
    static void * exclusive_task_handler ( void * arg )
    {
        Test * testptr = static_cast < Test * > ( arg );
        pthread_rwlock_wrlock (& testptr - > rwlock );
        / / 做专属任务在这里
        + +计数;
        COUT < < “写-计数=” < <计数< < ENDL ;
        if ( pthread_rwlock_unlock (& testptr - > rwlock ) )
        {
            COUT < < “写解锁错误” < < ENDL ;
        }
        返回NULL ;
    }
    
公众 :
    typedef void * (* ThreadFunc ) ( void * );
    void start ()
    {
        srand (time (NULL ));
        
        if ( pthread_rwlock_init (& rwlock ,NULL ) )
        {
            COUT < < “rwlock中初始化错误” < < 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失败” < < ENDL ;
                退出( 1 );
            }
        }
        rwlock中
        for (int i = 0 ; i < THREADS_NO ; i + + )
        {
            pthread_join ( threads [ i ] ,NULL );
        }
        删除[ ]线程;
    }
} ;

int main ()
{
    测试tmptest ;
    tmptest 。start ();
}

output:

book @ book -桌面:〜/分享$ 。/ posix_read_write_lock
写- - count = 1
写- -计数= 2
写- -计数= 3
读- - -计数= 3
读- - -计数= 3
读- - -计数= 3
读- - -计数= 3
写- -计数= 4
读- - - count = 4
写- -计数= 5
写- -计数= 6
读- - - count = 6
读- - - count = 6
读- - - count = 6
读- - - count = 6
写- -计数= 7
写- - count = 8
读- - - count = 8
读- - - count = 8
写- - count = 9
写- -计数= 10
读- - - count = 10
读- - - count = 10
读- - - count = 10
读- - - count = 10
读- - - count = 10
读- - - count = 10
读- - - count = 10
写- -计数= 11
写- -计数= 12
写- -计数= 13
写- -计数= 14
写- -计数= 15
读- - -计数= 15

 

二:利用pthread_cond_ *&pthread_mutex_ *实现rw_lock

code:

#include < pthread 。h >
#include < cstdlib >
#include < ctime >
#include < iostream >
using namespace std ;

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 );
        而 ( wr_cnt > 0 )
        {
            pthread_cond_wait (& rw_cond ,& cnt_mutex );
        }
        rd_cnt + + ;
        pthread_mutex_unlock (& cnt_mutex );
    }

    void release_shared_lock ()
    {
        pthread_mutex_lock (& cnt_mutex );
        rd_cnt - - ;
        if ( 0 = = rd_cnt )
        {
            pthread_cond_signal (& rw_cond );
        }
        pthread_mutex_unlock (& cnt_mutex );
    }

    void get_exclusive_lock ()
    {
        pthread_mutex_lock (& cnt_mutex );
        while ( rd_cnt + wr_cnt > 0 )
        {
            pthread_cond_wait (& rw_cond ,& cnt_mutex );
        }
        wr_cnt + + ;
        pthread_mutex_unlock (& cnt_mutex );
    }

    void release_exclusive_lock ()
    {
        pthread_mutex_lock (& cnt_mutex );
        wr_cnt - - ;
        pthread_cond_broadcast (& rw_cond );
        pthread_mutex_unlock (& cnt_mutex );
    }

    ~ RWLock ()
    {
        pthread_mutex_destroy (& cnt_mutex );
        pthread_cond_destroy (& rw_cond );
    }
} ;

static int count = 0 ;
课堂考试
{
私人的 : 
    RWLock锁;
    
    static void * shared_task_handler ( void * arg )
    {
        Test * testptr = static_cast < Test * > ( arg );
        testptr - >锁定。get_shared_lock ();
        / /     做共享在这里的任务
        COUT < < “读---计数=” < <计数< < ENDL ;
        testptr - >锁定。release_shared_lock ();
    }
    
    static void * exclusive_task_handler ( void * arg )
    {
        Test * testptr = static_cast < Test * > ( arg );
        testptr - >锁定。get_exclusive_lock ();
        / / 做专属任务在这里
        + +计数;
        COUT < < “写-计数=” < <计数< < ENDL ;
        testptr - >锁定。release_exclusive_lock ();
    }
    
公众 :
    typedef void * (* ThreadFunc ) ( void * );
    void start ()
    {
        srand (time (NULL ));

        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失败” < < ENDL ;
                退出( 1 );
            }
        }

        for (int i = 0 ; i < THREADS_NO ; i + + )
        {
            pthread_join ( threads [ i ] ,NULL );
        }

        删除[ ]线程;
    }
} ;

int main ()
{
    测试tmptest ;
    tmptest 。start ();
}

output:

book @ book -桌面:〜/分享$ 。/ read_write_lock
读- - - count = 0
读- - - count = 0
读- - - count = 0
写- - count = 1
读- - - count = 1
读- - - count = 1
读- - - count = 1
读- - - count = 1
写- -计数= 2
写- -计数= 3
读- - -计数= 3
读- - -计数= 3
读- - -计数= 3
读- - -计数= 3
读- - -计数= 3
读- - -计数= 3
读- - -计数= 3
读- - -计数= 3
读- - -计数= 3
读- - -计数= 3
读- - -计数= 3
读- - -计数= 3
读- - -计数= 3
写- -计数= 4
写- -计数= 5
写- -计数= 6
写- -计数= 7
写- - count = 8
写- - count = 9
写- -计数= 10
写- -计数= 11
读- - -计数= 11
写- -计数= 12
写- -计数= 13
读- - - count = 13
读- - - count = 13
写- -计数= 14
写- -计数= 15
写- -计数= 16
写- -计数= 17
写- -计数= 18
写- -计数= 19
读- - - count = 19
写- -计数= 20
读- - -计数= 20
写- -计数= 21
读- - -计数= 21
写- -计数= 22
读- - -计数= 22
读- - -计数= 22
写- -计数= 23
读- - -计数= 23
读- - -计数= 23
读- - -计数= 23
写- -计数= 24
读- - -计数= 24
写- -计数= 25
写- -计数= 26
写- -计数= 27
写- -计数= 28
读- - -计数= 28
读- - -计数= 28
写- -计数= 29
写- -计数= 30
读- - -计数= 30
读- - -计数= 30
读- - -计数= 30
写- -计数= 31
读- - -计数= 31
读- - -计数= 31
写- -计数= 32
读- - -计数= 32
写- -计数= 33
读- - -计数= 33
读- - -计数= 33
读- - -计数= 33
读- - -计数= 33
读- - -计数= 33
写- -计数= 34
写- -计数= 35

 

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值