linux内核并发,Linux内核--并发(示例代码)

为什么会产生并发

1、多个用户同时登陆的时候,他们有可能在任何时刻以任意的组合调用内核代码。

2、smp系统可能同时在不同的处理器上执行你的代码。

3、内核代码是抢占式的,你的程序有可能随时被剥夺掉处理器。

4、设备中断可能导致并发的异步事件。

5、内核也提供了各种延迟代码执行机制,如工作队列等,任务队列和定时器,它可以使你在与当前进程无关的方法中运行代码

并发带来的影响

并发产生了竞争条件,比如两个进程同时访问相同的硬件资源

应对的基本原则是:尽量避免共享数据

如果无法避免那就一定要注意共享的数据。

Linux 的 信号量

#include

/*

* Copyright (c) 2008 Intel Corporation

* Author: Matthew Wilcox

*

* Distributed under the terms of the GNU GPL, version 2

*

* Please see kernel/semaphore.c for documentation of these

functions

*/

#ifndef __LINUX_SEMAPHORE_H

#define __LINUX_SEMAPHORE_H

#include

#include

/* Please don‘t access any members of this structure directly */

struct semaphore {

raw_spinlock_t lock;

unsigned int count;

struct list_head wait_list;

};

#define __SEMAPHORE_INITIALIZER(name , n)

{

.lock = __RAW_SPIN_LOCK_UNLOCKED((name).lock),

.count = n,

.wait_list = LIST_HEAD_INIT((name).wait_list),

} #

define DEFINE_SEMAPHORE(name) struct semaphore name = __SEMAPHORE_INITIALIZER(name , 1)

static inline void sema_init(struct semaphore *sem, int val)

{

static struct lock_class_key __key;

*sem = (struct semaphore) __SEMAPHORE_INITIALIZER(*sem, val);

lockdep_init_map(&sem->lock.dep_map , "semaphore ->lock", &__key , 0);

}

extern void down(struct semaphore *sem);

extern int __must_check down_interruptible(struct semaphore *sem);

extern int __must_check down_killable(struct semaphore *sem);

extern int __must_check down_trylock(struct semaphore *sem);

extern int __must_check down_timeout(struct semaphore *sem, long jiffies);

extern void up(struct semaphore *sem);

#endif /* __LINUX_SEMAPHORE_H */

down方法将信号量的值减一然后等到信号量的值大于等于零继续执行。

down_interruptible跟down类似但是可以被中断,建议使用这个API,只使用down容易造成该线程永远无法退出。

一般的使用方法是:

if (down_interruptible(&sem))

return -ERESTARTSYS;

读写信号量

一种常见的信号量,针对共享文件,允许多个线程同时读,而读的时候不允许写。在同一时间只允许一个线程写。

#include

自旋锁

自旋锁最初是为了SMP系统设计的,实现在多处理器情况下保护临界区。

自旋锁只有两种状态,上锁,未上锁,经常被用来确保一段代码的原子性

spinlock API:

void spin_lock(spinlock_t *lock);

void spin_lock_irqsave(spinlock_t *lock , unsigned long flags);

void spin_lock_irq(spinlock_t *lock);

void spin_lock_bh(spinlock_t *lock);

读写自旋锁

linux内核提供了读写自旋锁,实际上它与读写信号量很相似。

上锁的要求

1、如果你在自己的代码里实现了一个设备锁,而你也要套用到linux内核提供的锁,请先把自己的锁锁上,再把系统的锁锁上。

2、如果你使用信号量和自旋锁,请先down信号量,再使用自旋锁。

3、确保自旋锁内没有其他的锁,以防系统被死锁。

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值