linux线程间同步(1)读写锁
读写锁比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, 出错则返回错误编号.
实例代码
/************************************************************** pthread_rwlock_test2.c:验证读写锁的默认顺序* 如果在main函数中用pthread_rwlock_wrlock上锁,那么* 如果所有线程都阻塞在写锁上的时候,优先处理的是被阻塞的写锁* 然后才处理读出锁* 如果在main函数中用pthread_rwlock_rdlock上锁,那么* 如果有读者正在读的时候即使后面到来的写者比另外一些到来的读者更早* 也是先处理完读者,才转而处理写者,这样会导致写饥饿* * 由此(执行结果)可以看出,LINUX平台默认的是读者优先,如果想要以写者优先* 则需要做一些处理**************************************************************/
#include <stdio.h>
#include <pthread.h>
#include <stdlib.h>pthread_rwlock_t rwlock;void *readers(void *arg)
{pthread_rwlock_rdlock(&rwlock);printf("reader %d got the lock\n", (int)arg);pthread_rwlock_unlock(&rwlock);//return NULL;
}
void *writers(void *arg)
{pthread_rwlock_wrlock(&rwlock);printf("writer %d got the lock\n", (int)arg);pthread_rwlock_unlock(&rwlock);//return NULL;
}int main(int argc, char **argv)
{int retval, i;pthread_t writer_id, reader_id;pthread_attr_t attr;int nreadercount = 1, nwritercount = 1;if (argc != 2) {fprintf(stderr, "usage, <%s threadcount>", argv[0]);return -1;}retval = pthread_rwlock_init(&rwlock, NULL);if (retval) {fprintf(stderr, "init lock failed\n");return retval;}pthread_attr_init(&attr);//pthread_attr_setdetachstate用来设置线程的分离状态//也就是说一个线程怎么样终止自己,状态设置为PTHREAD_CREATE_DETACHED//表示以分离状态启动线程pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED);//分别在main函数中对读出者和写入者加锁,得到的处理结果是不一样的pthread_rwlock_wrlock(&rwlock);
// pthread_rwlock_rdlock(&rwlock);for (i = 0; i < atoi(argv[1]); i++) {if (random() % 2) {pthread_create(&reader_id, &attr, readers, (void *)nreadercount);printf("create reader %d\n", nreadercount++);} else {pthread_create(&writer_id, &attr, writers, (void *)nwritercount);printf("create writer %d\n", nwritercount++);}}printf("main unlock\n");pthread_rwlock_unlock(&rwlock);sleep(5);//sleep是为了等待另外的线程的执行return 0;
}
参考:
- LINUX_IPC
linux线程间同步(1)读写锁相关推荐
- linux线程间同步(1)互斥锁与条件变量
线程的最大特点是资源的共享性,但资源共享中的同步问题是多线程编程的难点.linux下提供了多种方式来处理线程同步,最常用的是互斥锁.条件变量和信号量以及读写锁. 互斥锁(mutex) 互斥锁,是一种信 ...
- Linux多线程编程---线程间同步(互斥锁、条件变量、信号量和读写锁)
本篇博文转自http://zhangxiaoya.github.io/2015/05/15/multi-thread-of-c-program-language-on-linux/ Linux下提供了 ...
- linux线程同步(3)-读写锁
一.概述 读写锁与互斥量的功能类似,对临界区的共享资源进行保护!互斥量一次只让一个线程进入临界区, ...
- 线程间通信方式Linux,线程间的通信、同步方式与进程间通信方式
1.线程间的通信方式 使用全局变量 主要由于多个线程可能更改全局变量,因此全局变量最好声明为volatile 使用消息实现通信 在Windows程序设计中,每一个线程都可以拥有自己的消息队列(UI线程 ...
- linux线程间通信优点,进程间通信与线程间通信【转】
一个进程写管道:写入字节数小于PIPE_BUF是原子操作,写操作在管道缓冲区没有及时读走时发生阻塞. 一个进程读管道:读操作在管道缓冲区没有数据时发生阻塞. 以前一直想找个机会总结一下进程和线程的通信 ...
- Linux 线程间通信方式、进程通信方式
Linux线程间通信几种主要的手段 1. 管道: 管道(Pipe)及有名管道(named pipe):管道可用于具有亲缘关系进程间的通信,有名管道克服了管道没有名字的限制,因此,除具有 ...
- 进程间通信 和 线程间同步
以前经常搞混,所以记录下来. 进程间通信主要是指多个进程间的数据交互. 而线程间同步主要指维护多个线程之间数据准确.一致性. 一.进程间通信主要有以下几种方式: 管道(pipe):管道是一种半双工的通 ...
- 50.Linux 线程三 同步
Linux系统中常用实现线程同步的方式有三种,分别为互斥锁.条件变量与信号量. 下面将对这三种方式逐一进行讲解. 4.1 互斥锁 使用互斥锁实现线程同步时,系统会为共享资源添加一个称为互斥锁的标记,防 ...
- LinuxC高级编程——线程间同步
LinuxC高级编程--线程间同步 宗旨:技术的学习是有限的,分享的精神是无限的. 1. 互斥锁mutex 多个线程同时访问共享数据时可能会冲突.对于多线程的程序,访问冲突的问题是很普遍的,解决的办法 ...
最新文章
- 拒绝conda, 用virtualenv构建多版本的python开发环境
- Oracle Database Appliance ODA开箱视频
- 常用python编程软件-学习编程语言常用的10个工具、库——每个程序员都应该知道...
- java ssl证书生成_java – 使用jdk中提供的keytool生成SSL证书
- 强连通分量的分解(转博客园)
- 前端实现mac笔记本停靠栏效果
- 桌面虚拟化最佳实践4—存储规划(下)
- Unable to execute dex: Multiple dex files define Lcom/kenai/jbosh/AbstractAttr
- android简单小程序完整代码_10行代码实现小程序支付功能!丨实战
- java8根据某个id删选_Java 8可选:如何使用它
- 单调栈 leetcode整理(一)
- GP学习(三)—How to run a geoprocessing tool
- 根据拼音首字母查询人名【转】
- ASP.NETf发送邮件
- 如何实现自己的股票量化交易接口?
- 从 Sentence-BERT 谈句子表征
- bulk of the 用法_初中英语语法总结:冠词用法详解
- 函数名和变量名重名问题
- ubuntu14.04+caffe2
- error MIDL2455: The feature cannot be used on the target system
热门文章
- 汇编语言笔记(三): 标志寄存器
- 与时间相关的java源码_Java 基于当前时间获取和计算时间
- redis在java中的方法_redis在java中的使用方法
- win10子系统ubuntu图形界面_win10系统中安装ubuntu子系统及图形界面
- linux摄像头内核驱动开发,怎么在Linux下开发摄像头驱动
- matlab从矩阵中取rp开头文件,matlab trainrp
- Java基础学习需要掌握哪些内容?
- java汉字如何通过字节传输,求助,java中怎么用字节流读写汉字
- C语言和其他高级语言的最大的区别是什么?
- 天正双击墙体不能编辑_今日设计分享:CAD常用快捷键、Ps快捷键大全、天正快捷键总结!...