Linux中的同步互斥

【版权申明】未经博主同意,谢绝转载!(请尊重原创,博主保留追究权) 

Linux中的同步互斥

1. 什么是同步?

生活中的例子:
   洗菜必须在买菜之后, 做菜必须在洗菜之后, 吃饭必须在做菜之后.

软件上的概念:
   指的是散落在不同线程/进程中的代码片段, 他们的执行顺序必须是有序, 因为B代码片段的执行依赖着A代码片段的结果, 同理C代码片段的执行依赖着B代码片段的结果.
   那么, 怎么实现ABC的有序执行呢? 这就是同步的任务. 同步用于保证这几个代码片段的执行是有序的.

2. 什么是互斥?

生活中的例子:
   同一时间, 茅坑(马桶)只能有一个人蹲着, 人在进入厕所时会把门锁上, 在上一个人没有出来前, 其他人没办法进去. 这就是互斥.如果你一定要用这个厕所, 但是发现厕所已经被其他人使用着, 根据你的反应, 存在两种情况:

  1. 在门口等, 等上一个人使用完立刻进去; 这个叫阻塞, 期间你没办法做任何事;
  2. 过一会再回来看看是否可以上厕所, 这个叫非阻塞, 期间你可以做其他事情, 例如给阿姨倒一杯卡布奇洛.

软件上的概念:
   针对系统的某些资源, 同一时间内只允许一个进程/线程进行访问, 当资源被占用时, 其它进程/线程不得占用, 这就是互斥. 当有一个进程/线程, 需要访问该资源, 而该资源被其它进程/线程占用时, 有存在两种情况:

  1. 进程/线程原地等待(自旋等待/睡眠等待), 期间不会做其它事情, 直到获取到该资源. 这个就是阻塞;
  2. 进程/线程先去做其他事情, 等会再次查询该资源是否可用, 这个就是非阻塞.

3. 同步与互斥的关系

个人观点: 同步互斥更像一种兄弟关系, 没必要分谁是谁的什么, 但是两者通常一起出现.

   买菜->洗菜->做菜->吃饭, 这个流程中必须保持同步(有序进行), 但是过程中并不互斥, 哪一个地方, 都可以插入多个人, 但是菜同一时间可能只有一个人碰. 同步中存在着互斥.
   上厕所为例子, 你必须先锁上门, 然后才开始上厕所. 互斥中存在着同步.

代码也源于生活, 不是吗?

4. Linux同步互斥的代码实现

4.1 应用层
int fd = open("/dev/yangbkDevice", O_RDWR | O_NONBLOCK);	// 非阻塞方式打开文件, 默认是阻塞

int ret = read(fd, &value, 4);
4.2 驱动层

使用原子变量: (同一时间内只有一个进程/线程可以修改它的值, 通过这个变量的数值改变来进行判断, 在原子变量改变的前后只有一个进程/线程访问这段代码/资源)

//定义原子变量并初始化为1
static atomic_t canopen = ATOMIC_INIT(1);

// 在驱动的open()函数中, 当需要执行临界区的代码/访问敏感资源时, 试图修改原子变量以试图得到权限.
/**
 * atomic_dec_and_test - decrement and test
 * @v: pointer of type atomic_t
 *
 * Atomically decrements @v by 1 and
 * returns true if the result is 0, or false for all other
 * cases.
 */
if (!atomic_dec_and_test(&canopen))
{
	atomic_inc(&canopen);
	return -EBUSY;
}

// 操作/资源访问完成时, 释放权限.
atomic_inc(&canopen);

使用互斥锁:

//定义互斥锁
static DECLARE_MUTEX(button_lock);

// 在驱动的open()函数中
static int btn_open(struct inode *inode, struct file *file)
{
	if (file->f_flags & O_NONBLOCK)	
	{	// 判断fd是否以非阻塞方式打开, 若是以非阻塞方式打开, 不能立刻获得互斥锁则直接返回.
		if (down_trylock(&button_lock))
			return -EBUSY;
	}
	else
	{	// 否则是以阻塞方式打开, 故在原地等待锁被释放被获取锁.
		down(&button_lock);
	}
}

tips: 在驱动的read()函数中, 也需要判断fd是否以非阻塞方式打开, 也需要遵循O_NONBLOCK

// 释放互斥锁
up(&button_lock);

5. 总结

   同步与互斥只是一个概念, 需要程序员去遵循的规则, 以防止程序跑飞.

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

安河桥

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值