Linux内核并发与竞争-互斥量
Posted Wireless_Link
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Linux内核并发与竞争-互斥量相关的知识,希望对你有一定的参考价值。
一.互斥量的概念
在 FreeRTOS 和 UCOS 中也有互斥体,将信号量的值设置为 1 就可以使用信号量进行互斥访问了,虽然可以通过信号量实现互斥,但是 Linux 提供了一个比信号量更专业的机制来进行互斥,它就是互斥体—mutex。互斥访问表示一次只有一个线程可以访问共享资源,不能递归申请互斥体。在我们编写 Linux 驱动的时候遇到需要互斥访问的地方建议使用 mutex。 Linux 内核 使用 mutex 结构体表示互斥体,定义如下(省略条件编译部分):
struct mutex
/* 1: unlocked, 0: locked, negative: locked, possible waiters */
atomic_t count;
spinlock_t wait_lock;
;
在使用 mutex 之前要先定义一个 mutex 变量。在使用 mutex 的时候要注意如下几点:
①、 mutex 可以导致休眠,因此不能在中断中使用 mutex,中断中只能使用自旋锁。
②、和信号量一样, mutex 保护的临界区可以调用引起阻塞的 API 函数。
③、因为一次只有一个线程可以持有 mutex,因此,必须由 mutex 的持有者释放 mutex。并且 mutex 不能递归上锁和解锁。
二.互斥量的函数
三.互斥量的实验
#include <linux/types.h>
#include <linux/init.h>
#include <linux/interrupt.h>
#include <linux/mm.h>
#include <linux/slab.h>
#include <linux/spinlock.h>
#include <linux/module.h>
#include <linux/device.h>
#define CHRDEVBASE_MAJOR 200
uint8_t kernel_buffer[1024] = 0;
static struct class *hello_class;
struct mutex lock;
static int hello_world_open(struct inode * inode, struct file * file)
printk("hello_world_open\\r\\n");
/* 获取信号量 */
if (mutex_lock_interruptible(&lock))
return -ERESTARTSYS;
printk("hello_world_open success\\r\\n");
return 0;
static int hello_world_release (struct inode * inode, struct file * file)
printk("hello_world_release\\r\\n");
mutex_unlock(&lock);
return 0;
static const struct file_operations hello_world_fops =
.owner = THIS_MODULE,
.open = hello_world_open,
.release = hello_world_release,
.read = NULL,
.write = NULL,
;
static int __init hello_driver_init(void)
int ret;
printk("hello_driver_init\\r\\n");
mutex_init(&lock);
ret = register_chrdev(CHRDEVBASE_MAJOR,"hello_driver",&hello_world_fops);
hello_class = class_create(THIS_MODULE,"hello_class");
device_create(hello_class,NULL,MKDEV(CHRDEVBASE_MAJOR,0),NULL,"hello"); /* /dev/hello */
return 0;
static void __exit hello_driver_cleanup(void)
printk("hello_driver_cleanup\\r\\n");
device_destroy(hello_class,MKDEV(CHRDEVBASE_MAJOR,0));
class_destroy(hello_class);
unregister_chrdev(CHRDEVBASE_MAJOR,"hello_driver");
module_init(hello_driver_init);
module_exit(hello_driver_cleanup);
MODULE_LICENSE("GPL");
以上是关于Linux内核并发与竞争-互斥量的主要内容,如果未能解决你的问题,请参考以下文章
[架构之路-38]:目标系统 - 系统软件 - Linux OS硬件设备驱动必须熟悉的六大工作机制之(并发与互斥阻塞与非阻塞异步通知)
[架构之路-38]:目标系统 - 系统软件 - Linux OS硬件设备驱动必须熟悉的六大工作机制之(并发与互斥阻塞与非阻塞异步通知)