linux驱动程序中的并发控制-7(互斥体(mutex))-49

Posted 杨斌并

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了linux驱动程序中的并发控制-7(互斥体(mutex))-49相关的知识,希望对你有一定的参考价值。

互斥体(mutex)

互斥体(mutex)使用

  1. 定义互斥体(#include <linux/mutex.h>)
  • 结构体
struct mutex {
	/* 1: unlocked, 0: locked, negative: locked, possible waiters */
	atomic_t		count;
	spinlock_t		wait_lock;
	struct list_head	wait_list;
#if defined(CONFIG_DEBUG_MUTEXES) || defined(CONFIG_MUTEX_SPIN_ON_OWNER)
	struct task_struct	*owner;
#endif
#ifdef CONFIG_MUTEX_SPIN_ON_OWNER
	struct optimistic_spin_queue osq; /* Spinner MCS lock */
#endif
#ifdef CONFIG_DEBUG_MUTEXES
	void			*magic;
#endif
#ifdef CONFIG_DEBUG_LOCK_ALLOC
	struct lockdep_map	dep_map;
#endif
};
  • 定义
struct mutex my_mutex;
  1. 初始化互斥体
 mutex_init(&my_mutex);
  1. 获取互斥体
extern void mutex_lock(struct mutex *lock);
extern int __must_check mutex_lock_interruptible(struct mutex *lock);
extern int mutex_trylock(struct mutex *lock);
  • mutex_lock和mutex_lock_interruptible函数的区别仅仅在于阻塞时是否可被中断打断。
  • mutex_lock 函数不可被中断打断,mutex_lock_interruptible 函数可被中断打断。
  • mutex_trylock 函数获取互斥体时不会被阻塞。如果成功获取了互斥体,则立即返回1,否则立即返回0。
  1. 释放互斥体
mutex_unlock(&my_mutex);

实例

  • mutex_test.c
//
//  mutex_test.c
//  seqlock_demo
//
//  Created by lianfei on 2021/7/13.
//

#include <linux/module.h>
#include <linux/init.h>
#include <linux/kernel.h>
#include <linux/fs.h>
#include <linux/miscdevice.h>
#include <linux/uaccess.h>
#include <linux/delay.h>

#define DEVICE_RCU_NAME "mutex"

struct mutex my_mutex;

static ssize_t demo_read(struct file *file, char __user * buf, size_t count, loff_t *ppos){
    
    struct timeval tv;
    
    do_gettimeofday(&tv);
    printk("muxte read: start %ld\\n", tv.tv_sec);
    mutex_lock(&my_mutex);
    mdelay(10000);
    mutex_unlock(&my_mutex);
    do_gettimeofday(&tv);
    printk("muxte read: end %ld\\n", tv.tv_sec);
    
    return 0;
}


static ssize_t demo_write(struct file *file, const char __user *buf, size_t count, loff_t *ppos){
    struct timeval tv;
    do_gettimeofday(&tv);
    printk("muxte write: start %ld\\n", tv.tv_sec);
    mutex_lock(&my_mutex);
    mdelay(5000);
    mutex_unlock(&my_mutex);
    do_gettimeofday(&tv);
    printk("muxte write: end %ld\\n", tv.tv_sec);
    
    return count;
}

static int demo_release (struct inode *node, struct file *file){
    return 0;
}

static int demo_open (struct inode *node, struct file *file){
    return 0;
}

static struct file_operations dev_fops={
    .owner = THIS_MODULE,
    .open = demo_open,
    .release = demo_release,
    .read = demo_read,
    .write = demo_write
};

static struct miscdevice misc={
    .minor = MISC_DYNAMIC_MINOR,
    .name = DEVICE_RCU_NAME,
    .fops = &dev_fops
};



static int demo_init(void){

    int ret=misc_register(&misc);
    if(ret < 0 ){
        printk("atomic_init is error\\n");
        return -1;
    }
    printk("demo_init_success\\n");
    mutex_init(&my_mutex);
    return ret;
}

static void demo_exit(void){
    printk("ademo_exit_success\\n");
    misc_deregister(&misc);
}

module_init(demo_init);
module_exit(demo_exit);
MODULE_LICENSE("GPL");
MODULE_AUTHOR("binbing.Yang");
  • 测试脚本
  • mutex_test.sh
#!/system/bin/sh

cat /dev/mutex &
cat /dev/mutex &
sleep 5
echo data > /dev/mutex
echo data > /dev/mutex

执行 mutex_test.sh 脚本文件后,需要等待5秒,然后执行demsg命令查看日志信息,如果两个write 时间不相等,则表明demo write 函数被阻塞了若干时间。

以上是关于linux驱动程序中的并发控制-7(互斥体(mutex))-49的主要内容,如果未能解决你的问题,请参考以下文章

linux驱动程序中的并发控制-7(互斥体(mutex))-49

Linux驱动开发原子操作自旋锁信号量互斥体

Linux驱动开发原子操作自旋锁信号量互斥体

Linux驱动设备中的并发控制

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

Linux内核并发与竞争-互斥量