linux中读写锁的rwlock介绍

读写锁比mutex有更高的适用性,可以多个线程同时占用读模式的读写锁,但是只能一个线程占用写模式的读写锁;

1,当读写锁是写加锁状态时, 在这个锁被解锁之前, 所有试图对这个锁加锁的线程都会被阻塞.

2,当读写锁在读加锁状态时, 所有试图以读模式对它进行加锁的线程都可以得到访问权,但是以写模式对它进行枷锁的线程将阻塞;

3,当读写锁在读模式锁状态时, 如果有另外线程试图以写模式加锁读写锁通常会阻塞随后的读模式锁请求, 这样可以避免读模式锁长期占用, 而等待的写模式锁请求长期阻塞;

这种锁适用对数据结构进行读的次数比写的次数多的情况下,因为可以进行读锁共享

API接口说明:

1)初始化和销毁

#include <pthread.h>

int pthread_rwlock_init(pthread_rwlock_t *restrict rwlock, const pthread_rwlockattr_t *restrict attr);
int pthread_rwlock_destroy(pthread_rwlock_t *rwlock); 成功则返回0, 出错则返回错误编号.

2)读加锁和写加锁
获取锁的两个函数是阻塞操作

#include <pthread.h>
int pthread_rwlock_rdlock(pthread_rwlock_t *rwlock);
int pthread_rwlock_wrlock(pthread_rwlock_t *rwlock);
int pthread_rwlock_unlock(pthread_rwlock_t *rwlock);
成功则返回0, 出错则返回错误编号.

3)非阻塞获得读锁和写锁
非阻塞的获取锁操作, 如果可以获取则返回0, 否则返回错误的EBUSY.

#include <pthread.h>

int pthread_rwlock_tryrdlock(pthread_rwlock_t *rwlock);
int pthread_rwlock_trywrlock(pthread_rwlock_t *rwlock); 成功则返回0, 出错则返回错误编号.

Unix网络编程-卷2:用互斥锁和信号量实现写者优先的读写锁

typedef struct
{
pthread_mutex_t rw_mutex; /* basic lock on this struct */
pthread_cond_t rw_condreaders; /* for reader threads waiting */
pthread_cond_t rw_condwriters; /* for writer threads waiting */
int rw_magic; /* for error checking */
int rw_nwaitreaders; /* the number waiting */
int rw_nwaitwriters; /* the number waiting */
int rw_refcount; /* -1:one w_mutex; 0:mutex free; >0:num of r_mutex */
/* 4-1 if writer has the lock, else # readers holding the lock */
} pthread_rwlock_t;
int
pthread_rwlock_rdlock(pthread_rwlock_t *rw)
{
int result; if (rw->rw_magic != RW_MAGIC) // 判断是否初始化了
return(EINVAL); if ( (result = pthread_mutex_lock(&rw->rw_mutex)) != )
return(result); /* 4give preference to waiting writers */
/**
* rw->rw_refcount < 0
* 写者持有读写锁
*
* rw->rw_nwaitwriters > 0 (rw->rw_refcount >= 0)
* 有写者等待
*/
while (rw->rw_refcount < || rw->rw_nwaitwriters > )
{
rw->rw_nwaitreaders++;
result = pthread_cond_wait(&rw->rw_condreaders, &rw->rw_mutex);
rw->rw_nwaitreaders--;
if (result != )
break;
}
if (result == )
rw->rw_refcount++; /* another reader has a read lock */ pthread_mutex_unlock(&rw->rw_mutex);
return (result);
}
/* end rdlock */

pthread_rwlock_rdlock

int
pthread_rwlock_wrlock(pthread_rwlock_t *rw)
{
int result; if (rw->rw_magic != RW_MAGIC)
return(EINVAL); if ( (result = pthread_mutex_lock(&rw->rw_mutex)) != )
return(result); /* 读写锁不可用 */
while (rw->rw_refcount != )
{
rw->rw_nwaitwriters++;
result = pthread_cond_wait(&rw->rw_condwriters, &rw->rw_mutex);
rw->rw_nwaitwriters--;
if (result != )
break;
}
if (result == )
rw->rw_refcount = -; pthread_mutex_unlock(&rw->rw_mutex);
return(result);
}
/* end wrlock */

pthread_rwlock_wrlock

int
pthread_rwlock_unlock(pthread_rwlock_t *rw)
{
int result; if (rw->rw_magic != RW_MAGIC)
return(EINVAL); if ( (result = pthread_mutex_lock(&rw->rw_mutex)) != )
return(result); if (rw->rw_refcount > )
rw->rw_refcount--; /* releasing a reader */
else if (rw->rw_refcount == -)
rw->rw_refcount = ; /* releasing a writer */
else
err_dump("rw_refcount = %d", rw->rw_refcount); /* 4give preference to waiting writers over waiting readers */
if (rw->rw_nwaitwriters > ) // writers first-------------
{
if (rw->rw_refcount == )
result = pthread_cond_signal(&rw->rw_condwriters);
}
else if (rw->rw_nwaitreaders > )
result = pthread_cond_broadcast(&rw->rw_condreaders); pthread_mutex_unlock(&rw->rw_mutex);
return(result);
}
/* end unlock */

pthread_rwlock_unlock

Unix IPC之读写锁的更多相关文章

  1. UNIX环境高级编程——线程同步之互斥锁、读写锁和条件变量(小结)

    一.使用互斥锁 1.初始化互斥量 pthread_mutex_t mutex =PTHREAD_MUTEX_INITIALIZER;//静态初始化互斥量 int pthread_mutex_init( ...

  2. UNIX环境高级编程——线程同步之读写锁以及属性

    读写锁和互斥量(互斥锁)很类似,是另一种线程同步机制,但不属于POSIX标准,可以用来同步同一进程中的各个线程.当然如果一个读写锁存放在多个进程共享的某个内存区中,那么还可以用来进行进程间的同步, 互 ...

  3. pthread_rwlock pthread读写锁

    原文: http://www.cnblogs.com/diegodu/p/3890450.html 使用读写锁 配置读写锁的属性之后,即可初始化读写锁.以下函数用于初始化或销毁读写锁.锁定或解除锁定读 ...

  4. Linux 读写锁

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

  5. 进程通信类型 管道是Linux支持的最初Unix IPC形式之一

    管道 Linux环境进程间通信(一) https://www.ibm.com/developerworks/cn/linux/l-ipc/part1/index.html 管道及有名管道 郑彦兴200 ...

  6. Linux 系统编程 学习:02-进程间通信1:Unix IPC(1)管道

    Linux 系统编程 学习:02-进程间通信1:Unix IPC(1)管道 背景 上一讲我们介绍了创建子进程的方式.我们都知道,创建子进程是为了与父进程协作(或者是为了执行新的程序,参考 Linux ...

  7. Linux 系统编程 学习:03-进程间通信1:Unix IPC(2)信号

    Linux 系统编程 学习:03-进程间通信1:Unix IPC(2)信号 背景 上一讲我们介绍了Unix IPC中的2种管道. 回顾一下上一讲的介绍,IPC的方式通常有: Unix IPC包括:管道 ...

  8. linux kernel RCU 以及读写锁

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

  9. linux c 线程间同步(通信)的几种方法--互斥锁,条件变量,信号量,读写锁

    Linux下提供了多种方式来处理线程同步,最常用的是互斥锁.条件变量.信号量和读写锁. 下面是思维导图:  一.互斥锁(mutex)  锁机制是同一时刻只允许一个线程执行一个关键部分的代码. 1 . ...

随机推荐

  1. Python之旅:列表

    Python列表脚本操作符 列表对 + 和 * 的操作符与字符串相似.+ 号用于组合列表,* 号用于重复列表. 如下所示: Python 表达式 结果 描述 len([1, 2, 3]) 3 长度 [ ...

  2. 团体程序设计天梯赛-练习集 L1-031. 到底是不是太胖了

    比较两个实型的数: 若两者相等,也许用a>/b会出错... 我又想到了codeforces有很多这样的坑... #include <stdio.h> #include <std ...

  3. HDU 6040 stl

    Hints of sd0061 Time Limit: 5000/2500 MS (Java/Others)    Memory Limit: 131072/131072 K (Java/Others ...

  4. expect详解及自动登录脚本的实现

    expect可以让一些交互的任务自动完成,我们可以将一些交互过程写入脚本,ssh登录就是一个简单的实现,下面将介绍expect的用法. 1 安装 yum install -y expect 2 语法介 ...

  5. python基础之02列表/元组/字典/set集合

    python中内置的数据类型有列表(list)元组(tuple)字典(directory). 1 list list是一种可变的有序的集合.来看一个list实例: #第一种方法: >>&g ...

  6. Docker应用四:搭建docker镜像仓库(包括自生成https证书、登陆认证)

    利用docker官网提供的registry镜像创建私有仓库 一.首先从docker官网拉取registry镜像: docker pull registry 二.然后运行该镜像: docker run ...

  7. 用js获取客户端IP地址

    <script src="http://pv.sohu.com/cityjson?ie=utf-8"></script> <script type=& ...

  8. enumerate 遍历numpy数组

    enumerate 遍历numpy数组 觉得有用的话,欢迎一起讨论相互学习~Follow Me 遍历一维数组 i,j 分别表示数组的 索引 和 存储的值 import numpy as np a=np ...

  9. [NOI1999] 棋盘分割

    COGS 100. [NOI1999] 棋盘分割 http://www.cogs.pro/cogs/problem/problem.php?pid=100 ★★   输入文件:division.in  ...

  10. MVC: Connection String

    背景: 之前项目使用的是DB first/Model first,现在要对EF升级的6.0,并且更换成Code first. 问题: 1. System.Data.Entity.Core.Metada ...