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线程间同步(1)读写锁的更多相关文章
- linux线程间同步方式汇总
抽空做了下linux所有线程间同步方式的汇总(原生的),包含以下几个: 1, mutex 2, condition variable 3, reader-writer lock 4, spin loc ...
- linux线程间同步方式总结梳理
线程间一般无需特别的手段进行通信,由于线程间能够共享数据结构,也就是一个全局变量能够被两个线程同时使用.只是要注意的是线程间须要做好同步! 使用多线程的理由: 1. 一个是和进程相比,它是一种非常&q ...
- Linux线程间同步的几种方式
信号量 信号量强调的是线程(或进程)间的同步:"信号量用在多线程多任务同步的,一个线程完成了某一个动作就通过信号量告诉别的线程,别的线程再进行某些动作(大家都在sem_wait的时候,就阻塞 ...
- 四十、Linux 线程——互斥锁和读写锁
40.1 互斥锁 40.1.1 介绍 互斥锁(mutex)是一种简单的加锁的方法来控制对共享资源的访问. 在同一时刻只能有一个线程掌握某个互斥锁,拥有上锁状态的线程能够对共享资源进行访问. 若其他线程 ...
- linux线程同步(3)-读写锁
一.概述 读写锁与互斥量的功能类似,对临界区的共享资源进行保护!互斥量一次只让一个线程进入临界区, ...
- UNIX环境高级编程——线程同步之读写锁以及属性
读写锁和互斥量(互斥锁)很类似,是另一种线程同步机制,但不属于POSIX标准,可以用来同步同一进程中的各个线程.当然如果一个读写锁存放在多个进程共享的某个内存区中,那么还可以用来进行进程间的同步, 互 ...
- Linux系统编程(29)——线程间同步(续篇)
线程间的同步还有这样一种情况:线程A需要等某个条件成立才能继续往下执行,现在这个条件不成立,线程A就阻塞等待,而线程B在执行过程中使这个条件成立了,就唤醒线程A继续执行.在pthread库中通过条件变 ...
- C#线程间同步无法关闭
用C#做了个线程间同步的小程序,但每次关闭窗口后进程仍然在,是什么原因? 解决方法: 要加一句 线程.IsBackground = true; 否则退出的只是窗体 上面的方法没看懂... MSDN上说 ...
- Linux多线程实践(6) --Posix读写锁解决读者写者问题
Posix读写锁 int pthread_rwlock_init(pthread_rwlock_t *restrict rwlock, const pthread_rwlockattr_t *rest ...
随机推荐
- Java 多线程均匀处理同一个List中的数据
需求:使用多线程来处理同一个List中的数据,希望每个线程处理的数量是均匀的 事例代码如下: public class Test { static class HandleThread extends ...
- SQL SERVER-约束
NOT NULL - 指示某列不能存储 NULL 值. UNIQUE - 保证某列的每行必须有唯一的值. PRIMARY KEY - NOT NULL 和 UNIQUE 的结合.确保某列(或两个列多个 ...
- 关于VMNet1、VMNet8、
关于vmnet1~~~~~vmnet8 2008年04月11日 星期五 23:18 先说vmnet0,实际上就是一个虚拟的网桥,这个网桥有很若干个端口,一个端口用于连接你的Host,一个端口用于连接你 ...
- cloudstack给已有zone加入物理网络
默认情况下,假设zone建立完后.cloudstack是不提供加入物理网络接口的. 基础架构- 域 - 物理网络 以下仅仅有我们创建zone的时候加入的物理网络 假设想在这个基础上加入一个物理网络是没 ...
- Codeforces Round #311 (Div. 2)题解
A. Ilya and Diplomas time limit per test 1 second memory limit per test 256 megabytes input standard ...
- Java生成验证码_转
为了防止用户恶意,或者使用软件外挂提交一些内容,就得用验证码来阻止,虽然这个会影响用户体验,但为了避免一些问题很多网站都使用了验证码;今天下午参考文档弄了一个验证码,这里分享一下;这是一个web工程, ...
- leetcode 题解 || Longest Common Prefix 问题
problem: Write a function to find the longest common prefix string amongst an array of strings. 寻找 0 ...
- APP信息获取接口
https://itunes.apple.com/lookup?id=APPID&callback=2 http://myapp.com/cgi-bin/mapp/mapp_info?type ...
- Devexpress控件使用一:GridControl
1.控件及列表展示 1).控件 2).构建表格,用于列表展示 3).gridControl绑定数据 4).调用绑定:BindDataSource(InitDt()); 5).展示列表 2.表格的列配置 ...
- Caffe Loss分析
Caffe_Loss 损失函数为深度学习中重要的一个组成部分,各种优化算法均是基于Loss来的,损失函数的设计好坏很大程度下能够影响最终网络学习的好坏.派生于 \(LossLayer\),根据不同的L ...