zoukankan      html  css  js  c++  java
  • 读写锁

     1、概述

      读写锁与互斥量类似,不过读写锁允许更高的并行性。互斥量要么是锁住状态,要么是不加锁状态,而且一次只有一个线程对其加锁。读写锁可以有三种状态:读模式下加锁状态,写模式下加锁状态,不加锁状态。一次只有一个线程可以占有写模式的读写锁,但是多个线程可用同时占有读模式的读写锁。读写锁也叫做共享-独占锁,当读写锁以读模式锁住时,它是以共享模式锁住的,当它以写模式锁住时,它是以独占模式锁住的。

    2、读写锁API

      读写锁的数据类型为pthread_rwlock_t。如果这个类型的某个变量是静态分配的,那么可通过给它赋常值PTHREAD_RWLOCK_INITIALIZER来初始化它。

    获取和释放读写锁:
    int pthread_rwlock_rdlock(pthread_rwlock_t *rwptr); //获取一个读出锁
    int pthread_rwlock_wrlock(pthread_rwlock_t *rwptr); //获取一个写入锁
    int pthread_rwlock_unlock(pthread_rwlock_t *rwptr); //释放一个写入锁或者读出锁
    都返回:成功时为0,出错时为正的Exxx值
    int pthread_rwlock_tryrdlock(pthread_rwlock_t *rwptr);
    int pthread_rwlock_trywrlock(pthread_rwlock_t *rwptr);
    都返回:成功时为0,出错时为正的Exxx值

    读写锁属性:
    int pthread_rwlock_init(pthread_rwlock_t *rwptr, const pthread_rwlockattr_t *attr)
    int pthread_rwlock_destroy(pthread_rwlock_t *rwptr);
    都返回:成功时为0,出错时为正的Exxx值

    int pthread_rwlockattr_init(pthread_rwlockattr_t *attr);
    int pthread_rwlockattr_destroy(pthread_rwlockattr_t *attr);
    都返回:成功时为0,出错时为正的Exxx值

    int pthread_rwlockattr_getpshared(const pthread_rwlockattr_t *attr, int *valptr);
    int pthread_rwlockattr_setpshared(pthread_rwlockattr_t *attr, int valptr);
    都返回:成功时为0,出错时为正的Exxx值

    读写锁在不同进程间共享:
    PTHREAD_PROCESS_SHARED

    线程取消
    通过由对方调用函数pthread_cancel,一个线程可以被同一个进程内的任何其他线程所取消(cancel):
    int pthread_cancel(pthread_t tid);
    都返回:成功时为0,出错时为正的Exxx值

    为处理被取消的可能情况,任何线程可以安装(压入)和删除(弹出)清理处理程序:
    void pthread_cleanup_push(void (*function)(void *), void *arg);
    void pthread_cleanup_pop(int execute);
    这些处理程序就是发生以下情况时被调用的函数:
    1. 调用线程被取消(有某个线程调用pthread_cancel完成)
    2. 调用线程自愿终止(或者通过调用pthread_exit,或者从自己的线程起始函数返回)

    写个程序实现读者-写者问题,程序如下:

    复制代码
    #include <stdio.h>
    #include <stdlib.h>
    #include <string.h>
    #include <unistd.h>
    #include <pthread.h>
    #include <errno.h>
    
    #define MAXDATA     1024
    #define MAXREDER    100
    #define MAXWRITER   100
    struct
    {
        pthread_rwlock_t   rwlock;   //读写锁
        char datas[MAXDATA];          //共享数据域
    }shared = {
        PTHREAD_RWLOCK_INITIALIZER
    };
    
    void *reader(void *arg);
    void *writer(void *arg);
    
    int main(int argc,char *argv[])
    {
        int i,readercount,writercount;
        pthread_t tid_reader[MAXREDER],tid_writer[MAXWRITER];
        if(argc != 3)
        {
            printf("usage : <reader_writer> #<readercount> #<writercount>
    ");
            exit(0);
        }
        readercount = atoi(argv[1]);  //读者个数
        writercount = atoi(argv[2]);   //写者个数
        pthread_setconcurrency(readercount+writercount);
        for(i=0;i<writercount;++i)
            pthread_create(&tid_writer[i],NULL,writer,NULL);
        sleep(1); //等待写者先执行
        for(i=0;i<readercount;++i)
            pthread_create(&tid_reader[i],NULL,reader,NULL);
        //等待线程终止
        for(i=0;i<writercount;++i)
            pthread_join(tid_writer[i],NULL);
        for(i=0;i<readercount;++i)
            pthread_join(tid_reader[i],NULL);
        exit(0);
    }
    void *reader(void *arg)
    {
        pthread_rwlock_rdlock(&shared.rwlock);  //获取读出锁
        printf("Reader begins read message.
    ");
        printf("Read message is: %s
    ",shared.datas);
        pthread_rwlock_unlock(&shared.rwlock);  //释放锁
        return NULL;
    }
    
    void *writer(void *arg)
    {
        char datas[MAXDATA];
        pthread_rwlock_wrlock(&shared.rwlock);  //获取写如锁
        printf("Writers begings write message.
    ");
        printf("Enter the write message: 
    ");
        gets(datas);   //写入数据
        strcat(shared.datas,datas);
        pthread_rwlock_unlock(&shared.rwlock);  //释放锁
        return NULL;
    }
    复制代码

    程序执行结果如下所示:

  • 相关阅读:
    leetcode5 Longest Palindromic Substring
    leetcode17 Letter Combinations of a Phone Number
    leetcode13 Roman to Integer
    leetcode14 Longest Common Prefix
    leetcode20 Valid Parentheses
    leetcode392 Is Subsequence
    leetcode121 Best Time to Buy and Sell Stock
    leetcode198 House Robber
    leetcode746 Min Cost Climbing Stairs
    tomcat下使用druid配置jnid数据源
  • 原文地址:https://www.cnblogs.com/alantu2018/p/8466257.html
Copyright © 2011-2022 走看看