如果锁定写锁,则阻止其他地方读或者写,此时写或者读只能等待。
如果锁定写锁,则允许其他的读,但不允许写,写只能等待。

使用流程:

声明一个读写锁:

rwlock_t mylock;

初始化:

rwlock_init(&mylock);

获得写锁:

 write_lock(&mylock);

释放写锁:

write_unlock(&mylock);

获得读锁:

 read_lock(&mylock);

释放读锁:

read_unlock(&mylock);

以下是驱动模块的代码:

#include <linux/uaccess.h>
#include <linux/fs.h>
#include <linux/stat.h>
#include <linux/cdev.h>
#include <linux/io.h>
#include <linux/gpio.h>
#include <linux/slab.h>
#include <linux/irq.h>
#include <linux/mutex.h>
#include <linux/interrupt.h>
#include <linux/bug.h>            /* For BUG_ON.  */
#include <linux/cpu.h>
#include <linux/init.h> /* Needed for the macros */
#include <linux/kernel.h> /* Needed for pr_info() */
#include <linux/module.h> /* Needed by all modules */
#include <linux/delay.h>
#include <linux/smp.h>
#include <linux/kernel_stat.h>
#include <linux/sched.h>
#include <linux/percpu-defs.h>
#include <linux/wait.h>
#include <linux/gpio/driver.h>
#include <linux/atomic.h>
#include <linux/platform_device.h>
#include <linux/poll.h>
#include <linux/kfifo.h>
#include <linux/rwlock_types.h>
#include <linux/rwlock.h>#define DELAY_CMD_WRITE   _IOW('A',0,unsigned int)
#define DELAY_CMD_READ   _IOW('A',1,unsigned int)#define MY_MAX_MINORS  1
#define   DEVICE_NAME  "device name 500"DEFINE_KFIFO(myfifo, char, 1024);struct my_device_data {struct cdev cdev;
};DECLARE_WAIT_QUEUE_HEAD(wq);rwlock_t mylock;static struct my_device_data devs[MY_MAX_MINORS];static int my_open(struct inode *inode, struct file *file) {pr_info("my_open \n");return 0;
}static ssize_t my_write(struct file *filp, const char __user *user_buffer,size_t size, loff_t *offset) {int ret;unsigned int len = 0;pr_info("write");ret = kfifo_from_user(&myfifo, user_buffer, size, &len);if (ret != 0) {pr_err("kfifo_from_user error");return 0;}if (len <= 0)return 0;*offset += len;wake_up(&wq);return len;
}static ssize_t my_read(struct file *filp, char __user *user_buffer,size_t count, loff_t *offset) {int ret;unsigned int len = 0;pr_info("read");ret = kfifo_to_user(&myfifo, user_buffer, count, &len);if (len <= 0)return 0;*offset += len;return len;
}unsigned int my_poll(struct file *flip, struct poll_table_struct *table) {int mask = 0;pr_info("my_poll \n");poll_wait(flip, &wq, table);if (kfifo_is_empty(&myfifo)) {} else {mask |= POLLIN | POLLRDNORM;}return mask;
}int my_close(struct inode *inode, struct file *flip) {pr_info("my_close \n");return 0;
}static long my_ioctl(struct file *file, unsigned int cmd, unsigned long arg) {pr_info("cmd %d\n", cmd);switch (_IOC_NR(cmd)) {case 0: {write_lock(&mylock);pr_info("write start\n");mdelay(5000);pr_info("write end\n");write_unlock(&mylock);break;}case 1: {read_lock(&mylock);pr_info("read start\n");mdelay(3000);pr_info("read end\n");read_unlock(&mylock);break;}default: {pr_info("default: \n");}}return 0;
}static const struct file_operations my_fops = { .owner = THIS_MODULE, .open =my_open, .read = my_read, .write = my_write, .poll = my_poll, .release =my_close, .unlocked_ioctl = my_ioctl,};static dev_t mydev;static __init int my_init(void) {int i;int err;pr_info("a3 init_module\n");err = alloc_chrdev_region(&mydev, 0, MY_MAX_MINORS, DEVICE_NAME);if (err != 0) {return err;}for (i = 0; i < MY_MAX_MINORS; i++) {/* initialize devs[i] fields */cdev_init(&devs[i].cdev, &my_fops);cdev_add(&devs[i].cdev, MKDEV(MAJOR(mydev), i), 1);}
rwlock_init(&mylock);
return 0;
}static void __exit my_exit(void) {int i;pr_info("a3 cleanup_module\n");for (i = 0; i < MY_MAX_MINORS; i++) {/* release devs[i] fields */cdev_del(&devs[i].cdev);}unregister_chrdev_region(mydev, MY_MAX_MINORS);
}module_init(my_init);
module_exit(my_exit);MODULE_LICENSE("GPL");
MODULE_AUTHOR("81553652@qq.com");
MODULE_DESCRIPTION("andy one-key driver");
MODULE_ALIAS("one-key");

应用程序的测试代码:

#include <stdint.h>
#include <sys/types.h>
#include <stdlib.h>
#include <unistd.h>
#include <fcntl.h>
#include <string.h>
#include <sys/ioctl.h>
#include <unistd.h>
#include <stdio.h>
#include <pthread.h>
#include <poll.h>#define DELAY_CMD_WRITE   _IOW('A',0,unsigned int)
#define DELAY_CMD_READ   _IOW('A',1,unsigned int)static void* write01(void *ptr) {int fd = open("/dev/t01", O_RDWR, O_NONBLOCK);if (fd < 0) {perror("open");printf("error open\n");return NULL;}printf("write start \n");ioctl(fd, DELAY_CMD_WRITE, 100);printf("write end \n");sleep(2);close(fd);return NULL;
}static void* read01(void *ptr) {int fd = open("/dev/t01", O_RDWR, O_NONBLOCK);if (fd < 0) {perror("open");printf("error open\n");return NULL;}printf("read start \n");ioctl(fd, DELAY_CMD_READ, 100);printf("read end \n");sleep(1);close(fd);return NULL;
}/***  one  write,*  two  read*/
int main() {pthread_t thread, thread2, thread3;pthread_create(&thread, NULL, write01, NULL);usleep(10*1000);pthread_create(&thread2, NULL, read01, NULL);pthread_join(thread, NULL);pthread_join(thread2, NULL);printf("main exit\n");return EXIT_SUCCESS;
}

测试代码说明:
由于第一个线程是写入,所以第二个线程只能等待写完成之后才能开始读操作。

linux内核之读写锁rwlock_t使用入门相关推荐

  1. Linux应用开发 - 读写锁

    Linux应用开发 - 读写锁 什么时候用到读写锁:多线程开发中,如果少数线程会对共享内存数据修改,多数线程只是读取共享数据的值,就适用于读写锁解决"线程间抢夺资源"的问题. 只要 ...

  2. linux内核驱动模块开发步骤及实例入门介绍

    最近在搞一个linux的项目,其中主要是在编写一些应用模块,对内核及其驱动模块涉及很少,遇到了一些驱动模块的问题时,临时查了些资料,大致了解了一下驱动模块开发的基本步骤和常规步骤,并从网上也收集到了一 ...

  3. linux操作系统之读写锁

    (1)读写锁:只有一把锁,但是有两种状态(读,写) 1)读写锁的三种状态:读锁,写锁,不加锁 2)读写锁特性(12字):写锁优先级高,写独占,读共享 1>写模式加锁时,解锁前,所有对该线程加锁的 ...

  4. linux 进程间读写锁,Linux系统编程—进程间同步

    我们知道,线程间同步有多种方式,比如:信号量.互斥量.读写锁,等等.那进程间如何实现同步呢?本文介绍两种方式:互斥量和文件锁. ##互斥量mutex 我们已经知道了互斥量可以用于在线程间同步,但实际上 ...

  5. Linux线程同步读写锁 rwlock

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

  6. linux内核 noreturn,读《ARM Linux 内核源代码剖析》.......第13章 setup_processor()

    setup_processor首先是查找保存相应处理器信息的结构体,然后根据结构体里的值,对处理器相关的各种变量进行设置. setup_processor static void __init set ...

  7. 【Linux内核】RW读写锁机制

    读写锁机制 Linux内核中读写锁的机制是一种多读单写的锁机制,它允许多个读操作同时进行,但只能有一个写操作进行.当有写操作时,所有读操作都会被阻塞,直到写操作完成. 在内核中,读写锁主要由以下两个结 ...

  8. 深度解析Linux读写锁逻辑

    一.Linux为何会引入读写锁? 除了mutex,在linux内核中,还有一个经常用到的睡眠锁就是rw semaphore(后文简称为rwsem),它到底和mutex有什么不同呢?为何会有rw sem ...

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

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

最新文章

  1. J2EE 第二阶段项目之编写代码(四)
  2. OpenStack 的 SR-IOV 虚拟机热迁移
  3. qpython3安装lxml_centos python安装lxml报错
  4. 深度 | 阿里云蒋江伟:什么是真正的云原生?
  5. 被阻塞的线程唤醒后的逻辑
  6. C#实现树的双亲表示法
  7. java hashtable 修改_Java Hashtable computeIfAbsent()用法及代码示例
  8. 苹果系统itunes连iphone连不上服务器,iphone连不上itunes怎么办,iphone连不上itunes的解决办法...
  9. TPS和QPS的区别和理解
  10. 丘成桐:数理与人文(官方完整版PDF下载)(公号回复“丘成桐数学”下载PDF典型资料,欢迎转发、赞赏支持科普)
  11. 本地图片转换Base64的方法,Base64码转换为本地图片
  12. 读书笔记-指数基金投资指南
  13. 巴西电商Olist数据分析项目:SQL+FineBI
  14. 2022无线蓝牙耳机选哪个?盘点超热门的蓝牙耳机品牌推荐
  15. UOJ#748-[UNR #6]机器人表演【dp】
  16. hosts文件如何修改?已解决
  17. sd和sem啥区别_SD与SEM区别
  18. Python(详解)找出一个整数的所有因子---显示所有的最小因子--素因子
  19. 网页后缀php,网页后缀php有什么含义
  20. LTE学习-RACH(1)

热门文章

  1. 任贤齐《如果没有你》
  2. 华为云数据库RDS for MySQL助力企业降本增效,确保业务稳定高效运行!
  3. about present work
  4. android曲线位移动画,Bezier曲线在Android动画中的应用
  5. swfupload在xp系统上360极速模式报302错误解决方法
  6. mousewheel鼠标滚轮事件响应及实例
  7. javascript屏蔽脏字
  8. 合并排序算法(详解)
  9. arcmap自动编号
  10. html弹跳动画效果,CSS弹跳动画效果的实现方法