这次当我给面试官提及到读写锁的时候,详细问了我的读写锁,我知道怎么回事,用法,但是具体没实践过,听过的还是不要给面试官说了,不然又给自己挖坑。

下面这个程序就是读写锁的程序,分别有两个读者,两个写着,当写着输入end的时候并且读者读到程序运行结束,里面的读写锁是动态初始化,最后用pthread_join(),主要主线程等待子线程运行完她才可以结束。对于现在锁,我才感觉到都是有套路的,都被玩坏了。初始化,处理的,最后是销毁的。此外,我还遇到的一个问题是当时忘记在写线程忘记休眠sleep,结果一直让我写,写,写,那么她就一直拿着cpu写,就算输入end也就结束不了,因为读线程根本执行不到。

#include <stdio.h>
#include <unistd.h>
#include <string.h>
#include <stdlib.h>
#include <pthread.h>
#include <bits/pthreadtypes.h>#define  WORK_SIZE  1024static  pthread_rwlock_t  rwlock;char work_area[WORK_SIZE];
int time_to_exit;void *thread_to_read_o(void *arg);
void *thread_to_read_t(void *arg);
void *thread_to_write_o(void *arg);
void *thread_to_write_t(void *arg);void *thread_to_read_o(void *arg)
{printf("thread read one try to get lock\n");pthread_rwlock_rdlock(&rwlock);while(strncmp("end",work_area,3) != 0){printf("this is thread read one\n");printf("the characters is %s\n",work_area);pthread_rwlock_unlock(&rwlock);sleep(2);pthread_rwlock_rdlock(&rwlock);while(work_area[0] == '\0'){pthread_rwlock_unlock(&rwlock);sleep(2);pthread_rwlock_rdlock(&rwlock);}}pthread_rwlock_unlock(&rwlock);time_to_exit = 1;pthread_exit(0);
}void *thread_to_read_t(void *arg)
{printf("thread read one try to get lock\n");pthread_rwlock_rdlock(&rwlock);while(strncmp("end",work_area,3) != 0){printf("this is thread read two\n");printf("the characters is %s\n",work_area);pthread_rwlock_unlock(&rwlock);sleep(5);pthread_rwlock_rdlock(&rwlock);while(work_area[0] == '\0'){pthread_rwlock_unlock(&rwlock);sleep(5);pthread_rwlock_rdlock(&rwlock);}}pthread_rwlock_unlock(&rwlock);time_to_exit = 1;pthread_exit(0);
}
void *thread_to_write_o(void *arg)
{printf("this is write thread one try to get lock\n");while(!time_to_exit){pthread_rwlock_wrlock(&rwlock);printf("this is write thread one\n,input some text,enter 'end'  to finish\n");fgets(work_area,WORK_SIZE,stdin);pthread_rwlock_unlock(&rwlock);sleep(15); // forget sleep,so write always}pthread_rwlock_unlock(&rwlock);pthread_exit(0);
}
void *thread_to_write_t(void *arg)
{sleep(10);while(!time_to_exit){pthread_rwlock_wrlock(&rwlock);printf("this is write thread two\n input some text,enter 'end' to finish\n");fgets(work_area,WORK_SIZE,stdin);pthread_rwlock_unlock(&rwlock);sleep(20);}pthread_rwlock_unlock(&rwlock);pthread_exit(0);
}int main(int argc,char *argv[])
{int retval;pthread_t a_thread,b_thread,c_thread,d_thread;void *thread_result;retval = pthread_rwlock_init(&rwlock,NULL);if(retval != 0){//  errorexit(1);}retval = pthread_create(&a_thread,NULL,thread_to_read_o,NULL);if(retval != 0){//  errorexit(1);}retval = pthread_create(&b_thread,NULL,thread_to_read_t,NULL);if(retval != 0){//  errorexit(1);}retval = pthread_create(&c_thread,NULL,thread_to_write_o,NULL);if(retval != 0){//  errorexit(1);}retval = pthread_create(&d_thread,NULL,thread_to_write_t,NULL);if(retval != 0){//  errorexit(1);}// suspend main threadpthread_join(a_thread,NULL);pthread_join(b_thread,NULL);pthread_join(c_thread,NULL);pthread_join(d_thread,NULL);// destroy rwlockpthread_rwlock_destroy(&rwlock);printf("main thread will exit\n");return 0;
}

关于读写锁的第二个程序,主要是测试读锁和写锁哪个更加优先的问题,linux默认的是读者优先

#include <stdio.h>
#include <pthread.h>
#include <stdlib.h>
#include <unistd.h>pthread_rwlock_t rwlock;void *readers(void *arg)
{pthread_rwlock_rdlock(&rwlock);printf("readers %d got the lock\n",(int)arg);pthread_rwlock_unlock(&rwlock);
}void *writes(void *arg)
{pthread_rwlock_wrlock(&rwlock);printf("write %d got the lock\n",(int)arg);pthread_rwlock_unlock(&rwlock);
}int main(int argc,char *argv[])
{int retval,i;pthread_t writer_id,reader_id;pthread_attr_t attr;int nreadercount = 1;int nwritercount = 1;if(argc != 2){// errorexit(1);}retval = pthread_rwlock_init(&rwlock,NULL);if(retval != 0){//errorexit(2);}pthread_attr_init(&attr);pthread_attr_setdetachstate(&attr,PTHREAD_CREATE_DETACHED);//   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,writes,(void *)nwritercount);printf("create writer %d\n",nwritercount++);}}//  sleep(10);pthread_rwlock_unlock(&rwlock);sleep(10);return 0;
}

在上面的程序中如果有这个pthread_rwlock_wrlock(&rwlock);那么就算读者先加锁了,这时写者来了,那么再来的读者就不能加锁了,写者一直等到第一个读者结束后自己在加锁。理论是这样的,但是实际的结果,确实有点偏差,先看图

第6个读者先得到了锁,我感觉这个里面做了优化,前9个因为加锁的缘故只能先创建完之后再执行线程,最后一个readers 6,内核已经知道迟早readers 6要执行的,既然内核现在拿着这个reader 6,内核就顺便执行,才不管你有么有pthread_rwlock_wrlock(&rwlock);

在上面的程序中如果有这个pthread_rwlock_rdlock(&rwlock),运行结果

如果有什么问题,欢迎指正

关于linux的读写锁相关推荐

  1. linux 进程 读写锁,linux 下实现高性能读写锁(read/write lock)

    前一篇文章分析了Windows slim read/write lock的工作原理.我们知道它的设计相当精妙,于是我们可以借鉴它的思路来设计linux下的读写锁. 在这个读写锁的设计上,需要注意的是l ...

  2. linux 文件读写锁,linux下的简单文件读写锁的操作

    设置文件锁 /* lock_set.c */ int lock_set(int fd, int type) { struct flock old_lock, lock; lock.l_whence = ...

  3. Linux多线程的同步------读写锁

    前面介绍过Linux多线程同步的另外两个方法------互斥锁和信号量 Linux多线程的同步-----信号量和互斥锁_神厨小福贵!的博客-CSDN博客 下面来看一下读写锁: 读写锁和互斥锁都带有一个 ...

  4. c程序封装linux,Linux系统使用C语言封装线程读写锁

    在Linux平台上已经有现成的线程读写锁pthread_rwlock_t以及相关API,现将这些API封装成与Win32平台上相同的接口,以便于编写跨平台程序.这些API包括pthread_rwloc ...

  5. Linux系统编程----16(线程同步,互斥量 mutex,互斥锁的相关函数,死锁,读写锁)

    同步概念 所谓同步,即同时起步,协调一致.不同的对象,对"同步"的理解方式略有不同.如,设备同步,是指在两 个设备之间规定一个共同的时间参考:数据库同步,是指让两个或多个数据库内容 ...

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

    读写锁比mutex有更高的适用性,可以多个线程同时占用读模式的读写锁,但是只能一个线程占用写模式的读写锁. 1. 当读写锁是写加锁状态时,在这个锁被解锁之前,所有试图对这个锁加锁的线程都会被阻塞: 2 ...

  7. linux 内核同步--理解原子操作、自旋锁、信号量(可睡眠)、读写锁、RCU锁、PER_CPU变量、内存屏障

    内核同步 内核中可能造成并发的原因: 中断–中断几乎可以在任何时刻异步发生,也就可以随时打断当前正在执行的代码. 软中断和tasklet–内核能在任何时刻唤醒或调度软中断和tasklet,打断当前正在 ...

  8. Linux——读写锁

    Linux下,为了线程安全,为我们提供了很多种锁. 读写锁: 我们在编写多线程的时候,我们可能需要经常去读取某个共享数据变量,但是相对要改写这个变量的机会相对较少.在读的过程中,往往伴随着查找的操作, ...

  9. 从自旋锁、睡眠锁、读写锁到 Linux RCU 机制讲解

    总结一下 O/S 课程里面和锁相关的内容. 本文是 6.S081 课程的相关内容总结回顾结合 Real World 的 Linux 讲解各种锁和 RCU lock free 机制原理, 前置知识是基本 ...

最新文章

  1. keras 的 example 文件 cnn_seq2seq.py 解析
  2. NeHe教程Qt实现——lesson10
  3. hyperopt中文文档:Interfacing-With-Other-Languages(在其他语言中使用hyperopt)
  4. 区块链BaaS云服务(34)新加坡艾达链ASC
  5. V-rep学习笔记:vrep中的实用工具
  6. MyBatis配置错误
  7. 快速理解网络通信协议
  8. [转载]傅里叶分析之掐死教程(完整版)更新于2014.06.06 - 与时间无关的故事 - 知乎专栏...
  9. 用Fiddler调试localhost
  10. java用JDBC连接数据库的方式
  11. UVA10010 Where's Waldorf?【水题】
  12. html5+css3方式实现mobie app的一些瓶颈
  13. javamail 发送、读取邮件
  14. Mysq 5.7l服务无法启动,没有报告任何错误
  15. java 注解解析_Java知识点总结(注解-解析注解)
  16. mac电脑投屏到小米盒子_苹果手机搜不到小米盒子怎么办?
  17. css 平移到某个位置_css怎么移图片位置?
  18. 广州高清卫星地图 用百度卫星地图服务器下载 含标签、道路数据叠加 可商用
  19. JDT操作AST重构if块
  20. git branch命令解析

热门文章

  1. 【高手分享:拼音/五笔输入法通用使用技巧】
  2. 结构体指针和结构体指针变量的区别
  3. 组件封装--button组件
  4. 【Linux】chmod、chown、chgrp区别和使用
  5. AFNetworking源码简单分析
  6. 金融业数字化转型全面提速背后 看华为如何与时俱进
  7. Gitbook:无法加载文件C:\Users\Administrator\AppData\Roaming\npm\\gitbook.ps1因为在此系统上禁止运行脚本的解决方法
  8. VS2017编译在XP环境下运行的程序
  9. FET335X核心板 序---用飞凌AM335X开始工作了
  10. MPLAB 创建新项目