zoukankan      html  css  js  c++  java
  • linux内核信号量

    用户态的信号量:
    System V 信号量
    Posix 信号量

    信号量是用于保护临界区的一种常用方法。它的使用和自旋锁类似。相同的是,只有得到信号量的进程才能执行临界区代码;不同的是,当获取不到信号量时,进程不会原地打转而是进入睡眠等待状态

    定义

    struct semaphore {
        spinlock_t      lock;
        unsigned int        count;
        struct list_head    wait_list;
    };

    初始化

    #define DECLARE_MUTEX(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);
    }
    
    #define init_MUTEX(sem)     sema_init(sem, 1)
    #define init_MUTEX_LOCKED(sem)  sema_init(sem, 0)

    sema_init:设置信号量sem的值为val
    init_MUTEX:初始化为互斥信号量(sem的值为1)
    init_MUTEX_LOCKED:初始化为互斥信号量(sem的值为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);

    down:会导致睡眠,因此不能在中断上下文使用
    down_interruptible:因为down而进入睡眠的进程不能被信号打断,但因为down_interruptible而进入睡眠状态的进程能被信号打断,信号也会导致该函数返回,这时候函数返回非0
    down_trylock:尝试获取信号量sem,如果能立即获得,它就获取该信号量并返回0,否则,返回非0。它不会导致调用者睡眠,可以在中断上下文使用

    释放

    extern void up(struct semaphore *sem);

    释放信号量sem,唤醒等待者

    举例

    DECLARE_MUTEX(sem);
    down(&sem);
    ...
    critical section
    ...
    up(&sem);

    自旋锁vs信号量
    信号量是进程级的,用于多个进程之间对资源的互斥,虽然也是在内核中,但是内核执行是以进程的身份,代表进程来争夺资源。如果竞争失败,会发生进程上下文切换,当前进程进入睡眠状态,CPU将运行其他进程。鉴于进程上下文切换的开销很大,只有当进程占用资源时间较长时,用信号量才是好的选择
    当所要保护的临界区访问比较短时,用自旋锁更方便,因为它节省上下文切换的时间。但是CPU得不到自旋锁会在那里空转直到其他执行单元解锁为止,所以要求锁不能在临界区长时间保留,否则会降低系统的效率

    :读写信号量待补充

  • 相关阅读:
    哀悼:设置我们的blog为银灰色
    五子棋算法详解——解决方案之二
    ActionScript3使用角度值控制游戏角色的动作和移动
    LR12中快照的一点使用
    转义字符的一些应用
    关联的一些设置及实践
    检查点函数实践
    LR12的log解释
    struts2的强大迭代标签:<s:iterator>
    正则表达式30分钟入门
  • 原文地址:https://www.cnblogs.com/zhangxuechao/p/11709687.html
Copyright © 2011-2022 走看看