linux读写锁

一.概述                                                   

读写锁与互斥量的功能类似,对临界区的共享资源进行保护!互斥量一次只让一个线程进入临界区,读写锁比它有更高的并行性。读写锁有以下特点:

1.如果一个线程用读锁锁定了临界区,那么其他线程也可以用读锁来进入临界区,这样就可以多个线程并行操作。但这个时候,如果再进行写锁加锁就会发生阻塞,写锁请求阻塞后,后面如果继续有读锁来请求,这些后来的读锁都会被阻塞!这样避免了读锁长期占用资源,防止写锁饥饿!

2.如果一个线程用写锁锁住了临界区,那么其他线程不管是读锁还是写锁都会发生阻塞!

二.函数接口                                           

1.创建读写锁

1.1:宏常量初始化

1 pthread_rwlock_t rwlock = PTHREAD_RWLOCK_INITIALIZER;

1.2:函数初始化

1 #include <pthread.h>
2 
3 int pthread_rwlock_init(pthread_rwlock_t *restrict rwlock, const pthread_rwlockattr_t *restrict attr);

rwlock:读写锁的pthread_rwlock_t结构指针

attr:读写锁的属性结构指针。不需要别的属性默认为NULL。

2.读写锁加锁与解锁

1 #include <pthread.h>
2 
3 int pthread_rwlock_rdlock(pthread_rwlock_t *rwlock);
4 int pthread_rwlock_wrlock(pthread_rwlock_t *rwlock);
5 int pthread_rwlock_unlock(pthread_rwlock_t *rwlock);

rwlock:创建的读写锁指针

3.其他类型的加锁

复制代码
1 #include <pthread.h>
2 #include <time.h>
3 
4 
5 int pthread_rwlock_tryrdlock(pthread_rwlock_t *rwlock);
6 int pthread_rwlock_trywrlock(pthread_rwlock_t *rwlock);
7 
8 int pthread_rwlock_timedrdlock(pthread_rwlock_t *restrict rwlock, const struct timespec *restrict abs_timeout);
9 int pthread_rwlock_timedwrlock(pthread_rwlock_t *restrict rwlock, const struct timespec *restrict abs_timeout);
复制代码

try类函数加锁:如果获取不到锁,会立即返回错误EBUSY!

timed类函数加锁:如果规定的时间内获取不到锁,会返回ETIMEDOUT错误!

4.销毁读写锁

#include <pthread.h>
int pthread_rwlock_destroy(pthread_rwlock_t *rwlock);

应用实例:

创建4个线程,2个线程读锁,2个线程写锁,观察4个线程进入临界区的顺序:

  1 /**
  2  *  * @file pthread_rwlock.c
  3  *   */
  4 
  5 #include <stdio.h>
  6 #include <stdlib.h>
  7 #include <string.h>
  8 #include <unistd.h>
  9 #include <pthread.h>
 10 using namespace std;
 11 /* 初始化读写锁 */
 12 pthread_rwlock_t rwlock = PTHREAD_RWLOCK_INITIALIZER;
 13 /* 全局资源 */
 14 class CSingle{
 15 public:
 16   static CSingle& instance(){
 17     static CSingle single;
 18     return single;
 19   }
 20   void setX(int y){
 21     this->x = y;
 22   }
 23   int getX(){
 24     return this->x;
 25   }
 26   int x;
 27 };
 28 int global_num = 10;
 29 
 30 void err_exit(const char *err_msg)
 31 {
 32     printf("error:%s\n", err_msg);
 33     exit(1);
 34 }
 35 
 36 /* 读锁线程函数 */
 37 void *thread_read_lock(void *arg)
 38 {
 39     char *pthr_name = (char *)arg;
 40 
 41     while (global_num)
 42     {
 43         /* 读加锁 */
 44         pthread_rwlock_rdlock(&rwlock);
 45     
 46         printf("线程%s进入临界区,global_num = %d, X:%d\n", pthr_name, global_num, CSingle::instance().getX());
 47         sleep(1);
 48         printf("线程%s离开临界区...\n", pthr_name);
 49 
 50         /* 读解锁 */
 51         pthread_rwlock_unlock(&rwlock);
 52 
 53         sleep(1);
 54     }
 55 
 56     return NULL;
 57 }
 58 
 59 /* 写锁线程函数 */
 60 void *thread_write_lock(void *arg)
 61 {
 62     char *pthr_name = (char *)arg;
 63 
 64     while (global_num)
 65     {
 66         /* 写加锁 */
 67         pthread_rwlock_wrlock(&rwlock);
 68 
 69         /* 写操作 */
 70         --global_num;
 71     CSingle::instance().setX(global_num);
 72         printf("线程%s进入临界区,global_num = %d, X:%d\n", pthr_name, global_num, CSingle::instance().getX());
 73         sleep(1);
 74         printf("线程%s离开临界区...\n", pthr_name);
 75 
 76         /* 写解锁 */
 77         pthread_rwlock_unlock(&rwlock);
 78 
 79         sleep(2);
 80     }
 81 
 82     return NULL;
 83 }
 84 
 85 int main(void)
 86 {
 87     pthread_t tid_read_1, tid_read_2, tid_write_1, tid_write_2;
 88 
 89     /* 创建4个线程,2个读,2个写 */
 90     if (pthread_create(&tid_read_1, NULL, thread_read_lock, (void *)"read_1") != 0)
 91         err_exit("create tid_read_1");
 92 
 93     if (pthread_create(&tid_read_2, NULL, thread_read_lock, (void *)("read_2")) != 0)
 94         err_exit("create tid_read_2");
 95 
 96     if (pthread_create(&tid_write_1, NULL, thread_write_lock, (void *)("write_1")) != 0)
 97         err_exit("create tid_write_1");
 98 
 99     if (pthread_create(&tid_write_2, NULL, thread_write_lock, (void *)("write_2")) != 0)
100         err_exit("create tid_write_2");
101 
102     /* 随便等待一个线程,防止main结束 */
103     if (pthread_join(tid_read_1, NULL) != 0)
104         err_exit("pthread_join()");
105     if (pthread_join(tid_read_2, NULL) != 0)
106         err_exit("pthread_join()");
107     if (pthread_join(tid_write_1, NULL) != 0)
108         err_exit("pthread_join()");
109     if (pthread_join(tid_write_2, NULL) != 0)
110         err_exit("pthread_join()");
111 
112     return 0;
113 }
linux读写锁

 

转载于:https://www.cnblogs.com/guxuanqing/p/7999855.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值