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

杨斌并 杨斌并     2022-12-07     584

关键词:

互斥体(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(代码片段)

互斥体(mutex)互斥体(mutex)使用定义互斥体(#include<linux/mutex.h>)结构体structmutex /*1:unlocked,0:locked,negative:locked,possiblewaiters*/ atomic_t count; spinlock_t wait_lock; structlist_head wait_list;#ifdefined(CONFIG_DEBUG_MUTEXES)||defined(CON... 查看详情

linux驱动开发原子操作自旋锁信号量互斥体(代码片段)

...片内存区域的情况,多个任务可能会相互覆盖掉内存中的数据,造成内存数据混乱。Linux系统并发主要原因多线程并发访问抢占式并发访问中断程序并发访问多核间并发访问通常需要对全局变量、设备结构体这些共享资源... 查看详情

linux并发与竞争(原子操作自旋锁信号量互斥体)(代码片段)

目录并发与竞争原子操作原子操作简介原子整形操作API函数原子位操作API函数自旋锁自旋锁简介自旋锁API函数其他类型的锁自旋锁使用注意事项信号量信号量简介信号量API函数互斥体互斥体简介互斥体API函数Linux是一个多任务操... 查看详情

linux驱动程序中的并发控制-6(读写信号量)-48(代码片段)

读写信号量读写信号量和信号量的关系与读写自旋锁和自旋锁的关系类似。读信号量和写信号量是互斥的,但允许N个读执行单元同时访问共享资源(同时获取读信号量),而最多只允许有一个写单元获取写信号量。读写信... 查看详情

rk3399平台开发系列讲解(同步与互斥篇)12.7linux并发控制机制总结

平台内核版本安卓版本RK3399Linux4.4Android7.1 查看详情

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

一.互斥量的概念在FreeRTOS和UCOS中也有互斥体,将信号量的值设置为1就可以使用信号量进行互斥访问了,虽然可以通过信号量实现互斥,但是Linux提供了一个比信号量更专业的机制来进行互斥,它就是互斥体—mutex... 查看详情

linux设备驱动的并发控制学习笔记(代码片段)

文章目录并发和竞态编译乱序和执行乱序并发控制机制中断屏蔽原子操作整型原子操作位原子操作自旋锁自旋锁的使用读写自旋锁顺序锁读-复制-更新信号量互斥体完成量并发和竞态并发:多个执行单元同时、并行被执行。... 查看详情

linux设备驱动中的并发

参考技术A并发就是多个执行单元或多个进程并行执行,而这多个执行单元对资源进行共享,比如访问同一个变量或同一个硬件资源,这个时候就很容易出现竞态(说简单点就是竞争同一个”女朋友”)。为了处理并发带来的问题,... 查看详情

linux驱动程序中的并发控制(原子操作)-43(代码片段)

原子操作整型的原子操作使对整型的int的操作变成原子操作,要依靠一个数据类型:atomic_t。此结构体定义在include/linux/types.h文件中,定义如下:typedefstruct intcounter;atomic_t;相关的api#include<asm/atomic.h>函数描述ATO... 查看详情

linux驱动程序中的并发控制-1(原子操作)-43(代码片段)

原子操作整型的原子操作使对整型的int的操作变成原子操作,要依靠一个数据类型:atomic_t。此结构体定义在include/linux/types.h文件中,定义如下:typedefstruct intcounter;atomic_t;相关的api#include<asm/atomic.h>函数描述ATO... 查看详情

linux驱动程序中的并发控制-6(读写信号量)-48(代码片段)

读写信号量读写信号量和信号量的关系与读写自旋锁和自旋锁的关系类似。读信号量和写信号量是互斥的,但允许N个读执行单元同时访问共享资源(同时获取读信号量),而最多只允许有一个写单元获取写信号量。读写信... 查看详情

linux驱动程序中的并发控制-6(读写信号量)-48(代码片段)

读写信号量读写信号量和信号量的关系与读写自旋锁和自旋锁的关系类似。读信号量和写信号量是互斥的,但允许N个读执行单元同时访问共享资源(同时获取读信号量),而最多只允许有一个写单元获取写信号量。读写信... 查看详情

linux驱动程序中的并发控制-8(完成量(completion))-50(代码片段)

完成量(completion)完成量用于一个执行单元等待另一个执行单元执行完成某项工作。也就是说,如果在执行某段代码之前必须要执行另一段代码,就要使用完成量。完成量(completion)使用定义完成量结构... 查看详情

linux驱动程序中的并发控制-8(完成量(completion))-50(代码片段)

完成量(completion)完成量用于一个执行单元等待另一个执行单元执行完成某项工作。也就是说,如果在执行某段代码之前必须要执行另一段代码,就要使用完成量。完成量(completion)使用定义完成量结构... 查看详情

第十一章

...修改共享数据。为了达到这些目的,就需要本章要讨论的并发控制技术。这些技术主要包括原子操作、自旋锁、RCU、信号量、互斥体和完成量。本章还为每一种并发控制技术配有完整的示例, 查看详情

linux驱动之并发与竞争(代码片段)

...同一片内存区域,这些任务可能会相互覆盖这段内存中的数据,造成内存数据混乱。针对这个问题必须要做处理,严重的话可能会导致系统崩溃。linux存在以下并发访问:①、多线程并发访问,Linux是多任务(线程)的... 查看详情

linux并发与竞争实验(代码片段)

...试实验程序编写运行测试在上一章中我们学习了Linux下的并发与竞争,并且学习了四种常用的处理并发和竞争的机制:原子操作、自旋锁、信号量和互斥体。本章我们就通过四个实验来学习如何在驱动中使用这四种机制。... 查看详情

linux驱动程序中的并发控制-4(顺序自旋锁)-46(代码片段)

顺序自旋锁顺序锁与读写自旋锁类似,只是为写锁赋予了更高的权限。在读写自旋锁中,读锁和写锁的优先级是相同的。当读锁获取读自旋锁时,写锁必须等待,直到临界区的代码执行完成,并释放读自旋锁... 查看详情