一.概述                                                   

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

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个线程进入临界区的顺序:

 /**
* * @file pthread_rwlock.c
* */ #include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <pthread.h>
using namespace std;
/* 初始化读写锁 */
pthread_rwlock_t rwlock = PTHREAD_RWLOCK_INITIALIZER;
/* 全局资源 */
class CSingle{
public:
static CSingle& instance(){
static CSingle single;
return single;
}
void setX(int y){
this->x = y;
}
int getX(){
return this->x;
}
int x;
};
int global_num = ; void err_exit(const char *err_msg)
{
printf("error:%s\n", err_msg);
exit();
} /* 读锁线程函数 */
void *thread_read_lock(void *arg)
{
char *pthr_name = (char *)arg; while (global_num)
{
/* 读加锁 */
pthread_rwlock_rdlock(&rwlock); printf("线程%s进入临界区,global_num = %d, X:%d\n", pthr_name, global_num, CSingle::instance().getX());
sleep();
printf("线程%s离开临界区...\n", pthr_name); /* 读解锁 */
pthread_rwlock_unlock(&rwlock); sleep();
} return NULL;
} /* 写锁线程函数 */
void *thread_write_lock(void *arg)
{
char *pthr_name = (char *)arg; while (global_num)
{
/* 写加锁 */
pthread_rwlock_wrlock(&rwlock); /* 写操作 */
--global_num;
CSingle::instance().setX(global_num);
printf("线程%s进入临界区,global_num = %d, X:%d\n", pthr_name, global_num, CSingle::instance().getX());
sleep();
printf("线程%s离开临界区...\n", pthr_name); /* 写解锁 */
pthread_rwlock_unlock(&rwlock); sleep();
} return NULL;
} int main(void)
{
pthread_t tid_read_1, tid_read_2, tid_write_1, tid_write_2; /* 创建4个线程,2个读,2个写 */
if (pthread_create(&tid_read_1, NULL, thread_read_lock, (void *)"read_1") != )
err_exit("create tid_read_1"); if (pthread_create(&tid_read_2, NULL, thread_read_lock, (void *)("read_2")) != )
err_exit("create tid_read_2"); if (pthread_create(&tid_write_1, NULL, thread_write_lock, (void *)("write_1")) != )
err_exit("create tid_write_1"); if (pthread_create(&tid_write_2, NULL, thread_write_lock, (void *)("write_2")) != )
err_exit("create tid_write_2"); /* 随便等待一个线程,防止main结束 */
if (pthread_join(tid_read_1, NULL) != )
err_exit("pthread_join()");
if (pthread_join(tid_read_2, NULL) != )
err_exit("pthread_join()");
if (pthread_join(tid_write_1, NULL) != )
err_exit("pthread_join()");
if (pthread_join(tid_write_2, NULL) != )
err_exit("pthread_join()"); return ;
}

linux读写锁

linux读写锁的更多相关文章

  1. linux 读写锁应用实例

    转自:http://blog.csdn.net/dsg333/article/details/22113489 /*使用读写锁实现四个线程读写一段程序的实例,共创建了四个新的线程,其中两个线程用来读取 ...

  2. Linux读写锁的使用

    读写锁是用来解决读者写者问题的,读操作可以共享,写操作是排它的,读可以有多个在读,写只有唯一个在写,写的时候不允许读. 具有强读者同步和强写者同步两种形式: 强读者同步:当写者没有进行写操作时,读者就 ...

  3. Linux 读写锁

    线程的读写锁函数: 1,读写锁的初始化与销毁,静态初始化的话,可以直接使用PTHREAD_RWLOCK_INITIALIZER. #include <pthread.h> int pthr ...

  4. Linux的线程同步对象:互斥量Mutex,读写锁,条件变量

        进程是Linux资源分配的对象,Linux会为进程分配虚拟内存(4G)和文件句柄等 资源,是一个静态的概念.线程是CPU调度的对象,是一个动态的概念.一个进程之中至少包含有一个或者多个线程.这 ...

  5. linux中读写锁的rwlock介绍-nk_ysg-ChinaUnix博客

    linux中读写锁的rwlock介绍-nk_ysg-ChinaUnix博客 linux中读写锁的rwlock介绍 2013-02-26 13:59:35 分类: C/C++   http://yaro ...

  6. linux 内核的另一个自旋锁 - 读写锁

    除spinlock外,linux 内核还有一个自旋锁,名为arch_rwlock_t.它的头文件是qrwlock.h,包含在spinlock.h,头文件中对它全称为"Queue read/w ...

  7. linux线程间同步(1)读写锁

    读写锁比mutex有更高的适用性,能够多个线程同一时候占用读模式的读写锁.可是仅仅能一个线程占用写模式的读写锁. 1. 当读写锁是写加锁状态时,在这个锁被解锁之前,全部试图对这个锁加锁的线程都会被堵塞 ...

  8. Linux系统编程 —读写锁rwlock

    读写锁是另一种实现线程间同步的方式.与互斥量类似,但读写锁将操作分为读.写两种方式,可以多个线程同时占用读模式的读写锁,这样使得读写锁具有更高的并行性. 读写锁的特性为:写独占,读共享:写锁优先级高. ...

  9. linux kernel RCU 以及读写锁

    信号量有一个很明显的缺点,没有区分临界区的读写属性,读写锁允许多个线程进程并发的访问临界区,但是写访问只限于一个线程,在多处理器系统中允许多个读者访问共享资源,但是写者有排他性,读写锁的特性如下:允许 ...

随机推荐

  1. linux & windows下重启oracle

    Linux:方法1 用root以ssh登录到linux,打开终端输入以下命令: cd $ORACLE_HOME #进入到oracle的安装目录 dbstart #重启服务器 lsnrctl start ...

  2. 赚钱的小生意,VC对你没兴趣

    创业者,赚钱的生意就不要去找VC(风险投资)了,因为人家对你的生意没有兴趣. 无论是创业者,VC,股权投资散户,都需要对一个"生意"的规模有个总体的认识. 就"生意&qu ...

  3. Luogu P1120 小木棍 [数据加强版]

    看了题目心中只有一个字——搜索!!! 但是很显然,朴素的搜索(回溯)绝壁超时. 剪枝&优化(要搞很多,要不然过不了) 1:从小到大搜索它们的因数,这样找到就exit. 2:将数据从大到小排序, ...

  4. 汇编 ADD指令

    知识点: 加法汇编指令ADD 一.加法指令 ADD(Addition) 格式 格式: ADD A,B //A=A+B; 功能: 两数相加 . OPRD1为任一通用寄存器或存储器操作数,可以是任意一个 ...

  5. git和github使用教程

    看官请移步git和github简单教程, 本文是上述链接的截图,担心哪天作者不小心删除了,备一份在自己这里,仅为自己看着方便.侵权请告知

  6. 前端示例MVC网站

    前端示例MVC网站 ASP.NET Zero 包含了一个公共web站点的前端页面和一个登陆页面.当您第一次运行项目的时候可以看到,如下图所示: 该前端网站有两个页面,一个是主页和关于我们.这些页面的内 ...

  7. [转载]JVM 垃圾回收机制(Garbage Collection)

    相关算法: 引用计数法 引用可达法 尚学堂 参考:http://www.sxt.cn/Java_jQuery_in_action/Principle_and_algorithm_of_garbage_ ...

  8. PHP学习笔记2

    PHP Switch语句 用于根据多个不同条件执行不同动作.如果不在每个条件后加break,将会输出所有结果. <?php $language="java"; switch( ...

  9. (第十二周)新功能WBS

    项目名:食物链教学工具 组名:奋斗吧兄弟 组长:黄兴 组员:李俞寰.杜桥.栾骄阳.王东涵 新增加的功能:背景音乐 功能 子功能 二级子功能 预计花费时间(小时) 实际花费时间(小时) 背景音乐 界面组 ...

  10. 实训一(cocos2d-x相关)

    实训内容简介: 大四开始前系里安排的的集中实践环节,根据要求,开发app应用软件. 目标app:Stick_mxj 目的:继续对cocos2d-x的学习,完成实践环节,解决现在对引擎不是很清楚的一些问 ...