简介: CSDN博客专家,专注Android/Linux系统,分享多mic语音方案、音视频、编解码等技术,与大家一起成长!
优质专栏:Audio工程师进阶系列【原创干货持续更新中……】🚀
优质专栏:多媒体系统工程师系列【原创干货持续更新中……】🚀
优质视频课程:AAOS车载系统+AOSP14系统攻城狮入门实战课【原创干货持续更新中……】🚀
人生格言: 人生从来没有捷径,只有行动才是治疗恐惧和懒惰的唯一良药.
🍉🍉🍉文章目录🍉🍉🍉
- 🌻1.前言
- 🌻2.Linux内核之up_read与up_write介绍
- 🐓2.1 读写信号量(RWSEM)
- 🐓2.2 up_read
- 🐓2.3 up_write
- 🐓2.4 重要性
- 🐓2.5 性能和扩展性
- 🐓2.6 结论
- 🌻3.代码实例
- 🐓3.1 读取信号量:保护共享资源的并发读取操作
- 🐓3.2 写入信号量:保护对共享资源的独占写入操作
- 🐓3.3 同时使用读取锁和写入锁来保护共享资源的读写操作
🌻1.前言
本篇目的:Linux内核之读写信号量:up_read/up_write用法实例
🌻2.Linux内核之up_read与up_write介绍
- 在 Linux 内核中,up_read 和 up_write 是用于管理读写信号量的函数,通常与 down_read 和 down_write 函数一起使用,用于实现读写锁。
- up_read函数:
作用:释放读取锁定信号量。
用法:up_read(&sem);
说明:up_read 函数用于释放先前通过 down_read 函数获取的读取锁。它使得其他进程或线程能够获取读取锁,允许多个并发读取操作。
- up_write:
作用:释放写入锁定信号量。
用法:up_write(&sem);
说明:up_write 函数用于释放先前通过 down_write 函数获取的写入锁。它使得其他进程或线程能够获取写入锁,允许其他写入或读取操作。
-
这些函数通常与读写锁信号量(如 rw_semaphore)一起使用,以确保对共享资源的并发访问的正确性和同步。读取锁(共享锁)允许多个读取者同时访问资源,但写入锁(互斥锁)要求独占访问,因此在写入时需要阻止其他读取者和写入者。
-
在Linux内核中,
up_read
和up_write
是用于操作读写信号量的两个重要函数。这些函数在内核的并发控制中扮演着关键角色,特别是在处理对共享资源的并发访问时。
🐓2.1 读写信号量(RWSEM)
- 首先,我们需要了解读写信号量(RWSEM)的概念。读写信号量是一种允许多个读者同时访问资源,但在写者访问时需要独占资源的同步机制。这种机制非常适合于读操作远多于写操作的场景,因为它可以显著提高系统的并发性能。
- 读写信号量包含两个计数器:
- 读计数器:记录当前有多少个读者持有信号量。
- 写计数器:当有写者等待或正在写入时,它会递增。
🐓2.2 up_read
up_read
函数用于增加读计数器,通常在读者完成对共享资源的访问后调用。这个函数的主要作用是释放对共享资源的读锁。如果释放后没有任何读者或写者持有信号量,它还会唤醒等待的写者。up_read
的基本步骤如下:
- 增加读计数器:如果有其他读者正在访问资源,
up_read
会增加读计数器。 - 检查写者等待状态:如果写者正在等待,
up_read
会检查是否有必要唤醒它们。 - 唤醒写者:如果没有读者或写者持有信号量,
up_read
会唤醒等待的写者。
🐓2.3 up_write
up_write
函数用于释放对共享资源的写锁。它通常在写者完成对共享资源的写入操作后调用。与up_read
不同,up_write
在释放写锁后,如果有读者或写者等待,它将负责唤醒这些等待的进程。up_write
的基本步骤如下:
- 减少写计数器:如果有写者持有信号量,
up_write
会减少写计数器。 - 检查读者和写者等待状态:
up_write
会检查是否有读者或写者正在等待。 - 唤醒等待的读者或写者:如果有等待的读者或写者,
up_write
会唤醒它们。
🐓2.4 重要性
up_read
和up_write
在Linux内核中非常重要,因为它们提供了一种有效的机制来控制对共享资源的并发访问。这种机制可以防止竞态条件,确保在多个进程或线程访问共享资源时的数据一致性。
🐓2.5 性能和扩展性
- 读写信号量在多处理器系统上特别有用,因为它们允许并发读取,从而提高了系统的整体性能。此外,它们还支持在多核处理器上的扩展性,这对于现代操作系统来说是至关重要的。
🐓2.6 结论
up_read
和up_write
是Linux内核中用于管理读写信号量的两个基本函数,它们在确保共享资源并发访问的正确性和性能方面发挥着关键作用。通过提供对共享资源的精细控制,这些函数为Linux内核的高效和稳定运行提供了支持。随着Linux内核的不断发展和优化,这些同步机制也在不断改进,以适应不断变化的硬件和软件需求。
🌻3.代码实例
🐓3.1 读取信号量:保护共享资源的并发读取操作
#include <linux/init.h>
#include <linux/module.h>
#include <linux/fs.h>
#include <linux/semaphore.h>static DEFINE_RWLOCK(my_rwlock);
static int shared_data = 0;static int __init read_lock_example_init(void)
{pr_info("Read lock example driver initialized\n");return 0;
}static void __exit read_lock_example_exit(void)
{pr_info("Read lock example driver exited\n");
}static int my_open(struct inode *inode, struct file *file)
{pr_info("Device opened\n");return 0;
}static ssize_t my_read(struct file *file, char *buf, size_t count, loff_t *pos)
{ssize_t bytes_read = 0;// 获取读取锁down_read(&my_rwlock);// 读取共享资源bytes_read = snprintf(buf, count, "Shared data: %d\n", shared_data);// 释放读取锁up_read(&my_rwlock);return bytes_read;
}static const struct file_operations my_fops = {.owner = THIS_MODULE,.open = my_open,.read = my_read,
};module_init(read_lock_example_init);
module_exit(read_lock_example_exit);MODULE_LICENSE("GPL");
🐓3.2 写入信号量:保护对共享资源的独占写入操作
#include <linux/init.h>
#include <linux/module.h>
#include <linux/fs.h>
#include <linux/semaphore.h>static DEFINE_RWLOCK(my_rwlock);
static int shared_data = 0;static int __init write_lock_example_init(void)
{pr_info("Write lock example driver initialized\n");return 0;
}static void __exit write_lock_example_exit(void)
{pr_info("Write lock example driver exited\n");
}static int my_open(struct inode *inode, struct file *file)
{pr_info("Device opened\n");return 0;
}static ssize_t my_write(struct file *file, const char *buf, size_t count, loff_t *pos)
{ssize_t bytes_written = 0;// 获取写入锁down_write(&my_rwlock);// 写入共享资源sscanf(buf, "%d", &shared_data);bytes_written = count;// 释放写入锁up_write(&my_rwlock);return bytes_written;
}static const struct file_operations my_fops = {.owner = THIS_MODULE,.open = my_open,.write = my_write,
};module_init(write_lock_example_init);
module_exit(write_lock_example_exit);MODULE_LICENSE("GPL");
🐓3.3 同时使用读取锁和写入锁来保护共享资源的读写操作
#include <linux/init.h>
#include <linux/module.h>
#include <linux/fs.h>
#include <linux/semaphore.h>static DEFINE_RWLOCK(my_rwlock);
static int shared_data = 0;static int __init mixed_lock_example_init(void)
{pr_info("Mixed lock example driver initialized\n");return 0;
}static void __exit mixed_lock_example_exit(void)
{pr_info("Mixed lock example driver exited\n");
}static int my_open(struct inode *inode, struct file *file)
{pr_info("Device opened\n");return 0;
}static ssize_t my_read(struct file *file, char *buf, size_t count, loff_t *pos)
{ssize_t bytes_read = 0;// 获取读取锁down_read(&my_rwlock);// 读取共享资源bytes_read = snprintf(buf, count, "Shared data: %d\n", shared_data);// 释放读取锁up_read(&my_rwlock);return bytes_read;
}static ssize_t my_write(struct file *file, const char *buf, size_t count, loff_t *pos)
{ssize_t bytes_written = 0;// 获取写入锁down_write(&my_rwlock);// 写入共享资源sscanf(buf, "%d", &shared_data);bytes_written = count;// 释放写入锁up_write(&my_rwlock);return bytes_written;
}static const struct file_operations my_fops = {.owner = THIS_MODULE,.open = my_open,.read = my_read,.write = my_write,
};module_init(mixed_lock_example_init);
module_exit(mixed_lock_example_exit);MODULE_LICENSE("GPL");