读写锁 顺序性linux,linux读写锁

一.概述

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

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

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

读写锁的优势往往展现在读操作很频繁,而写操作较少的情况下

二.函数接口

1.创建读写锁

1.1:宏常量初始化

1 pthread_rwlock_t rwlock = PTHREAD_RWLOCK_INITIALIZER;

1.2:函数初始化

1 #include

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

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.其他类型的加锁

48304ba5e6f9fe08f3fa1abda7d326ab.png

1 #include

2 #include

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);

48304ba5e6f9fe08f3fa1abda7d326ab.png

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

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

4.销毁读写锁

#include

int pthread_rwlock_destroy(pthread_rwlock_t *rwlock);

应用实例:

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

8f900a89c6347c561fdf2122f13be562.png

961ddebeb323a10fe0623af514929fc1.png

1 /**2 * * @file pthread_rwlock.c3 **/

4

5 #include

6 #include

7 #include

8 #include

9 #include

10 using namespacestd;11 /*初始化读写锁*/

12 pthread_rwlock_t rwlock =PTHREAD_RWLOCK_INITIALIZER;13 /*全局资源*/

14 classCSingle{15 public:16 static CSingle&instance(){17 staticCSingle single;18 returnsingle;19 }20 void setX(inty){21 this->x =y;22 }23 intgetX(){24 return this->x;25 }26 intx;27 };28 int global_num = 10;29

30 void err_exit(const char *err_msg)31 {32 printf("error:%s", 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", pthr_name, global_num, CSingle::instance().getX());47 sleep(1);48 printf("线程%s离开临界区...", pthr_name);49

50 /*读解锁*/

51 pthread_rwlock_unlock(&rwlock);52

53 sleep(1);54 }55

56 returnNULL;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", pthr_name, global_num, CSingle::instance().getX());73 sleep(1);74 printf("线程%s离开临界区...", pthr_name);75

76 /*写解锁*/

77 pthread_rwlock_unlock(&rwlock);78

79 sleep(2);80 }81

82 returnNULL;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读写锁

pthread中提供的锁有:pthread_mutex_t、pthread_spinlock_t、pthread_rwlock_t。

pthread_mutex_t是互斥锁,同一瞬间只能有一个线程能够获取锁,其他线程在等待获取锁的时候会进入休眠状态。因此pthread_mutex_t消耗的CPU资源很小,但是性能不高,因为会引起线程切换。

pthread_spinlock_t是自旋锁,同一瞬间也只能有一个线程能够获取锁,不同的是,其他线程在等待获取锁的过程中并不进入睡眠状态,而是在 CPU上进入“自旋”等待。自旋锁的性能很高,但是只适合对很小的代码段加锁(或短期持有的锁),自旋锁对CPU的占用相对较高。

pthread_rwlock_t是读写锁,同时可以有多个线程获得读锁,同时只允许有一个线程获得写锁。其他线程在等待锁的时候同样会进入睡眠。读写锁在互斥锁的基础上,允许多个线程“读”,在某些场景下能提高性能。

对于互斥锁,如果资源已经被占用,资源申请者只能进入睡眠状态。但是自旋锁不会引起调用者睡眠,如果自旋锁已经被别的执行单元保持,调用者就一直循环在那里看是否该自旋锁的保持者已经释放了锁,"自旋"一词就是因此而得名。

https://blog.youkuaiyun.com/JCPGEE/java/article/details/79377948

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值