ICode9

精准搜索请尝试: 精确搜索
首页 > 其他分享> 文章详细

读写锁

2019-11-07 22:07:32  阅读:197  来源: 互联网

标签:rwlock int 读写 pthread 线程 Pthread


先说点其他的,就是发现之前看的IPC(interprocess communication)资料是System V的(有点老旧,从博客中的书页截图就可以看出来,但是这本书的确不错),虽然说在我的最新版Ubuntu上还可以用,但我去看了POSIX和System V的区别好像POSIX更好一些,所以后面的IPC的学习就使用POSIX的。

1.概述

互斥锁将试图进入我们称之为临界区的所有其他线程都阻塞住。该临界区通常涉及这些线程共享的一个或者多个数据的访问或更新。然而有时候我们可以在读某个数据与修改某个数据之间作以区分。

读写锁的两条分配规则

  ①只要没有线程持有某个给定的读写锁用于写,那么任意数目的线程可以持有该读写锁用于读。

  ②仅当没有线程持有某个给定的读写锁用于读或用于写时,才能分配该读写锁用于写。

举个栗子,ATM机在没人用的时候大家可以围个圈去参观它,但是只有它在没人用它(参观的不算使用)时,其他人才可以用它。

某些应用中读数据比写数据频繁的多,这些应用可以从读写锁代替互斥锁中获益。任意给定时刻允许多个读出者存在提供了更高的并发度,同时在某个写入者修改数据期间保护该数据该数据,以免其他读者或写者干扰。

这种对于对某个给定资源的共享访问也称为 共享-独占  上锁。因为获取一个读写锁用于读称之为 共享锁,获取一个读写锁用于写称之为 独占锁。

2.获取与释放读写锁

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

 pthread_rwlock_rdlock获取一个读出锁,如果对应的读写锁已由某个写入者持有,那么久阻塞调用线程。pthread_rwlock_wrlock 获取一个写入锁,如果对应的写入锁已有另一个写入锁持有,或者已由一个或多个读出者持有,那就阻塞调用线程。pthread_rwlock_unlock 释放一个读出所或写入锁。

#include<pthread.h>
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,失败返回一个对应错误的正值

 下面两个函数尝试获取一个读出锁或写入锁,但是如果该锁不能马上取得,那就返回一个EBUSY错误,而不是把调用线程投入睡眠。

#include<pthread.h>
int pthread_rwlock_tryrdlock(pthread_rwlock_t *rwptr);
int pthread_rwlock_trywrlock(pthread_rwlock_t *rwptr);
//成功返回0,失败返回一个对应错误的正值

 3.读写锁属性

除了使用静态分配的方法给读写锁初始化,还可以使用 pthread_rwlock_init 来动态地初始化。当一个线程不再需要某个读写锁时,可以调用 pthread_rwlock_destory 摧毁它。

#include<pthread.h>
int pthread_rwlock_init(pthread_rwlock_t *rwptr, const pthread_rwlockattr_t *attr);
int pthread-rwlock_destory(pthread_rwlock_t *rwptr);
//成功返回0,失败返回一个对应错误的正值

 数据类型为 pthread_rwlockattr_t的某个属性对象一旦初始化,就通过调用不同的函数来启用或者禁止特定属性。当前定义了唯一的属性是 PTHREAD_PROCESS_SHARED ,它指定相应的读写锁在不同进程间共享,而不仅仅是在单个进程内的不同线程间共享。以下两个函数分别获取和设置这个属性。

#include<pthread.h>
int pthread_rwlockattr_getpshared(const pthread_rwlockattr_t *attr, int *valptr);
int pthread_rwlockattr_setpshared(pthread_rwlockattr_t *attr, int value);
//成功返回0,失败返回一个对应错误的正值

 第一个函数在由valptr指向的整数中返回该属性的当前值。第二个函数把该属性的当前值设置为value, 其值为 PTHREAD_PROXESS_PRIVATE,或者为 PTHREAD_PROCESS_SHARED。

 由于读写锁的特性,我设计了两个程序,测试其是否可以共读,写锁和读锁在同时竞争时,写锁是否有更高优先级。

例程1.

#include"main.h"
#include"time_rw.h"
#include"pthread_rwlock.h"

int main()
{
	pthread_t th1, th2, th3, th4, th5;
	Pthread_rwlock_init(&rw, NULL);
//	Pthread_create(&th1, &pthread1);
//	sleep(1);
//	Pthread_create(&th2, &pthread2);
	Pthread_create(&th3, &pthread3);
     sleep(1); Pthread_create(&th4, &pthread4); Pthread_create(&th5, &pthread5); sleep(15); }

 对程序先予以说明,线程1,2是给文件写的线程,线程3,4,5为读线程。

现在让线程3先创建,在其加锁后打印并休眠20秒。这时候如果线程4,5还可以访问,则说明其确实有共读性。

 

 在线程3未解锁的情况下,线程4,5仍然可以查看文件内容,足以说明其共读性。

 

#include"main.h"
#include"time_rw.h"
#include"pthread_rwlock.h"

int main()
{
	pthread_t th1, th2, th3, th4, th5;
	Pthread_rwlock_init(&rw, NULL);
	Pthread_create(&th1, &pthread1);
	sleep(1);
	Pthread_create(&th2, &pthread2);
	Pthread_create(&th3, &pthread3);
	//sleep(1);
	//Pthread_create(&th4, &pthread4);
	//Pthread_create(&th5, &pthread5);
	sleep(15);
}

 现在先让线程1运行,线程1用完锁以后释放,让线程2和线程3争抢读写锁,发现因为线程2是写锁,看起来其在与读锁争抢时有更高的优先级

 

 但是实际上我将线程2,3的创建顺序进行调换以后

 

 发现并不是,其优先级与创建顺序有关?

 

标签:rwlock,int,读写,pthread,线程,Pthread
来源: https://www.cnblogs.com/area-h-p/p/11806059.html

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有