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硬件设备驱动必须熟悉的六大工作机制之(并发与互斥阻塞与非阻塞异步通知)

Linux 并发与竞争(原子操作自旋锁信号量互斥体)

Linux 并发与竞争实验

Linux设备驱动中的并发

linux内核同步问题