读写锁

摘要:
标准时间>未发布h>整数=0;数字);pthreadrwlockunlock(&sleep(1);}Intmain(){inti;pthread_tp[8];//初始化读/写锁pthread_rwlock_init(&//3个写线程,用于(i=0;i++){pthread_create;

(1) 读写锁是几把锁
  一把锁
  pthread_rwlock_t lock;

(2) 读写锁的类型
  读锁: 对内存做读操作
  写锁: 对内存做写操作

(3) 读写锁的特性:
  线程A加读锁成功, 又来了三个线程, 做读操作, 可以加锁成功
    读共享, 并行处理
  线程A加写锁成功, 又来了三个线程, 做读操作, 三个线程阻塞
    写读占, 串行处理
  线程A加读锁成功, 又来了B线程加写锁阻塞, 在B之后来了C线程加读锁阻塞
    读写不能同时进行
    写的优先级高

(4) 读写锁场景练习
线程A加写锁成功, 线程B请求读锁:
  线程B阻塞
线程A持有读锁, 线程B请求写锁:
  线程B阻塞
线程A拥有读锁, 线程B请求读锁
  线程B加锁成功
线程A持有读锁, 然后线程B请求写锁, 然后线程B请求读锁
  B阻塞, C阻塞 --> 写的优先级高
  A解锁, B线程加写锁成功, C继续阻塞
  B解锁, C加读锁成功
线程A持有写锁, 然后线程B请求读锁, 然后线程C请求写锁
  B, C阻塞
  A解锁, C加写锁, B阻塞
  C解锁, B加锁成功

(5) 读写锁使用场景
互斥锁--> 读写串行
读写锁--> 读: 并行; 写: 串行
程序中读操作大于写操作

(6) 主要处理函数
int pthread_rwlock_init(pthread_rwlock_t *restrict rwlock, const pthread_rwlockattr_t *restrict attr); 初始化读写锁

int pthread_rwlock_destroy(pthread_rwlock_t *rwlock);销毁读写锁

int pthread_rwlock_rdlock(pthread_rwlock_t *rwlock);加读锁
  阻塞: 之前对这把锁加的写锁的操作
int pthread_rwlock_tryrdlock(pthread_rwlock_t *rwlock);尝试加读锁
  加锁成功: 0; 加锁失败: 错误号
int pthread_rwlock_wrlock(pthread_rwlock_t *rwlock);加写锁
  阻塞: 上一次加写锁还没有解锁; 上一次加读锁没解锁
int pthread_rwlock_trywrlock(pthread_rwlock_t *rwlock);尝试加写锁

int pthread_rwlock_unlock(pthread_rwlock_t *rwlock);解锁

(7) 读写锁和互斥锁, 并不是任何时候都能阻塞线程

(8) 练习
3个线程不定时写同一全局资源, 5个线程不定时读同一全局资源

#include <stdio.h>
#include <unistd.h>
#include <stdlib.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <string.h>
#include <pthread.h>

int number = 0;

// 读写锁
pthread_rwlock_t lock;

void *write_func(void *arg) {
    while (1) {
        pthread_rwlock_wrlock(&lock);
        number++;
        printf("+++++write: %lu, %d
", pthread_self(),  number);
        pthread_rwlock_unlock(&lock);
        sleep(1);
    }
    return NULL;
}

void *read_func(void *arg) {
    while (1) {
        pthread_rwlock_rdlock(&lock);
        printf("======read: %lu, %d
", pthread_self(), number);
        pthread_rwlock_unlock(&lock);
        sleep(1);
    }
    return NULL;
}

int main() {
    int i;
    pthread_t p[8];

    // 初始化读写锁
    pthread_rwlock_init(&lock, NULL);

    // 3个写线程
    for (i = 0; i < 3; i++) {
        pthread_create(&p[i], NULL, write_func, NULL);
    }
    
    // 5个读线程
    for (i = 3; i < 8; i++) {
        pthread_create(&p[i], NULL, read_func, NULL);
    }

    // 回收子线程
    for (i = 0; i < 8; i++) {
        pthread_join(p[i], NULL);
    }

    for (i = 0; i < 8; i++) {
        pthread_rwlock_destroy(&lock);
    }

    return 0;
}

免责声明:文章转载自《读写锁》仅用于学习参考。如对内容有疑问,请及时联系本站处理。

上篇frxReport 使用说明如何编写符合web标准的XHTML文档下篇

宿迁高防,2C2G15M,22元/月;香港BGP,2C5G5M,25元/月 雨云优惠码:MjYwNzM=

相关文章

RxJava入门

项目小版本上线,抽空简单学习了下久仰大名的RxJava 一、引入 个人觉得rxjava的特点: 强大灵活的事件流处理(多线程/多事件/复合对象) 强大灵活优雅简洁的异步 链式调用 可自动Lambda化   实现:RxJava 是通过一种扩展的观察者模式来实现的 类比 类比 实际 实际 职责 演讲者 Button (可)被订阅者 (同右)...

使用 suspend 和 resume 暂停和恢复线程

suspend 和 resume 的使用 在 Thread 类中有这样两个方法:suspend 和 resume,这两个方法是成对出现的。 suspend() 方法的作用是将一个线程挂起(暂停), resume() 方法的作用则是将一个挂起的线程重新开始并继续向下运行。 通过一个例子来看一下这两个方法的使用: public class SuspendT...

Python_实现json数据的jsonPath(精简版)定位及增删改操作

基于python实现json数据的jsonPath(精简版)定位及增删改操作   by:授客QQ:1033553122     实践环境 win7 64 Python 3.4.0   代码 #-*- encoding:utf-8 -*-   # author:授客   importre   defparse_sub_expr(sub_e...

百度地图在项目中的使用(JS)

废话先: 这个项目是使用ASP.NET MVC 写的,而关于百度地图在项目中的应用不限于ASP.NET MVC 因为我大部分的API的使用是通过Javascript,想在项目中使用百度地图,你得先成为百度的开发者,具体的步骤,在本篇博文中不多叙述。 主题: 在使用百度地图的时候,你得先要获得一个ak 这里就是点击创建应用,它提供了几个类别1.for...

openssl多线程实例

本示例用多线程实现了一个ssl服务端和一个客户端。 服务端代码如下: #include <stdio.h> #include <stdlib.h> #include <memory.h> #include <errno.h> #ifndef _WIN32 #include <sys/types.h>...

iOS:iOS开发中用户密码保存位置

原文来自简书:http://www.jianshu.com/p/4af3b8179136/comments/1294203 如果要实现自动登录,不必每次打开应用都去登录,我们势必要把密码保存到本地。一般我们的操作是:每次打开应用后,如果存在密码,直接进入界面,然后再进行后台密码验证。如果没网络,我们可以跳过验证;如果有网络,我们可以后台去验证帐号密码的正确...