linux 内核几种锁

//内核锁学习

内核锁有几种:
第一种:
//这里 val 是安排给旗标的初始值.
void sema_init(struct semaphore *sem, int val);

//结果是一个旗标变量( 称为 name ),
//初始化为 1 ( 使用 DECLARE_MUTEX ) 或者 0 (使用 DECLARE_MUTEX_LOCKED ).
DECLARE_MUTEX(name);
DECLARE_MUTEX_LOCKED(name);


// P 函数称为 down -- 或者这个名子的某个变体
//这里, "down" 指的是这样的事实, 这个函数递减旗标的值
void down(struct semaphore *sem);
int down_interruptible(struct semaphore *sem);
int down_trylock(struct semaphore *sem);


//一旦调用down的时候 则不再拥有旗标
void up(struct semaphore *sem);


第二种: 读者 写着旗标
//初始化
void init_rwsem(struct rw_semaphore *sem);

//读者接口

// down_read 的调用提供了对被保护资源的只读存取
//与其他读者可能地并发地存取. 注意 down_read 可能将调用进程置为不可中断的睡眠
// down_read_trylock 如果读存取是不可用时不会等待; 如果被准予存取它返回非零, 否则是 0.
//注意 down_read_trylock 的惯例不同于大部分的内核函数, 返回值 0 指示成功
void down_read(struct rw_semaphore *sem);
int down_read_trylock(struct rw_semaphore *sem);

//释放
void up_read(struct rw_semaphore *sem);

//写者接口
void down_write(struct rw_semaphore *sem);
int down_write_trylock(struct rw_semaphore *sem);

//释放
void up_write(struct rw_semaphore *sem);

//你可以使用 downgrade_write 在一旦你已完成改变后允许其他读者
void downgrade_write(struct rw_semaphore *sem);


第三种:
// completion 是任务使用的一个轻量级机制: 允许一个线程告诉另一个线程工作已经完成.

//初始化
DECLARE_COMPLETION(my_completion);

或者, 如果 completion 必须动态创建和初始化:

struct completion my_completion;
/* ... */
init_completion(&my_completion);


//等待 completion 是一个简单事来调用
void wait_for_completion(struct completion *c);


//如果多于一个线程在等待同一个 completion 事件, 这 2 个函数做法不同. complete 只唤醒一个等待的线程,
//而 complete_all 允许它们所有都继续. 在大部分情况下, 只有一个等待者, 这 2 个函数将产生一致的结果
void complete(struct completion *c);
void complete_all(struct completion *c);

//下面列一个example
DECLARE_COMPLETION(comp);
ssize_t complete_read (struct file *filp, char __user *buf, size_t count, loff_t *pos)
{
    printk(KERN_DEBUG "process %i (%s) going to sleep\n",current->pid, current->comm);
    wait_for_completion(&comp);
    printk(KERN_DEBUG "awoken %i (%s)\n", current->pid, current->comm);
    return 0; /* EOF */
}

ssize_t complete_write (struct file *filp, const char __user *buf, size_t count, loff_t *pos)
{
    printk(KERN_DEBUG "process %i (%s) awakening the readers...\n", current->pid, current->comm);
    complete(&comp);
    return count; /* succeed, to avoid retrial */
}


//清理
void complete_and_exit(struct completion *c, long retval);


第四种:  自旋锁


//初始化spin_lock
spinlock_t my_lock = SPIN_LOCK_UNLOCKED;
//或者在运行时使用:
void spin_lock_init(spinlock_t *lock);

//在进入一个临界区前, 你的代码必须获得需要的 lock
void spin_lock(spinlock_t *lock);


//为释放一个你已获得的锁
void spin_unlock(spinlock_t *lock);

 

//实际上有 4 个函数可以加锁一个自旋锁:
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)


//也有 4 个方法来释放一个自旋锁
void spin_unlock(spinlock_t *lock);
void spin_unlock_irqrestore(spinlock_t *lock, unsigned long flags);
void spin_unlock_irq(spinlock_t *lock);
void spin_unlock_bh(spinlock_t *lock);

//还有一套非阻塞的自旋锁操作:
//这些函数成功时返回非零( 获得了锁 ), 否则 0. 没有"try"版本来禁止中断.
int spin_trylock(spinlock_t *lock);
int spin_trylock_bh(spinlock_t *lock);

 

 

 


 

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值