linux 2.6同步机制

    操作系统的同步机制是老话题了,不过技术的东西放久不用了就容易忘记,在这里就信号量为大家整理一下思绪。

    在linux系统中,信号量是一种可以睡眠的锁。如果进程A希望占有一个正在被进程B使用的信号量时,进程A会被推入等待队列,然后睡眠。直到进程B将持有的信号量释放,处于等待队列中的进程A才会被唤醒,并获得信号量。

    从信号量的特点所得出的一些结论,如下:

    • 由于等待信号量的进程会睡眠,因此信号量适用于需要长时间占用临界资源的情况,即临界区较长。


    • 相反,如果临界区很短,就不适合用信号量,因为进入睡眠,唤醒,维护等待队列这一系列动作,可能比等待临界区资源的时间还要长。


    • 等待信号量的进程会睡眠,因此不可以在中断处理中使用信号量,因为在中断上下文中是不能进行调度的。


    • 占用信号量的时候,不能再次占用自旋锁,因为等待信号量的进程会睡眠,而等待自旋锁的进程不可以睡眠。



    如何在自旋锁和信号量之间做个选择呢,即临界区短就用自旋锁,临界区长就用信号量,当然禁止睡眠的地方是不可以使用信号量的。

    信号量的另一个特性是,同一时刻允许任意数量的持有者,相比自旋锁同一时刻只能允许一个持有者,信号量在某些场合是非常有优势的。

    因此在linux中,信号量又分为两种:
    1. 同一时刻可被多个持有者占有的信号量称为计数信号量 sem
    2. 同一时刻只允许一个持有者占用的信号量称为互斥信号量 mutex

    互斥信号量用的比较多一些,信号量到底可以允许几个持有者,是在声明信号量的时候用参数控制的。

    struct semaphore ,这便是linux中信号量的数据类型,可以通过一下方式静态的声明信号量:
    static DECLARE_SEMAPHORE_GENERIC(name, count);

    其中参数,name自然是指信号量的名字,count就是刚才提到过的持有者的数量,如果希望创建一个互斥量,可以简单的使用下面的宏:
    static DECLARE_MUTEX(name);

    当你需要用kmalloc动态创建一个信号量时,可以用sem_init(sem, count)来初始化动态创建的信号量,当然用下面的简单调用可以初始化动态创建的互斥信号量:
    init_MUTEX(sem);

    说了这么多,下面贴上一段代码,和大家说说从声名,到使用一个信号量的完整过程:

    /* 在全局位置上,定义并声名一个互斥信号量, 名字为test_sem */
    static DECLARE_MUTEX(test_sem);

    /* 在某个函数中, 希望获取信号量 */
    if (down_interruptible(&test_sem)) { /* 在这里,down_interruptible会让我们睡眠 */
            return;  /* 信号量被占用,无法获取*/    
    }

    /* 临界区 */
    ......

    /* 释放信号量 */
    up(&test_sem);

    我们说说down_interruptible,它会试图获取信号量,但如果发现其已经被持有,down_interruptible会让当前的进程进入等待队列并睡眠。当然,这种睡眠是可以被打断的,可以响应信号,如果使用另一个获取信号量的函数 - down(),那就不能被信号打断,会一直睡在那里,直到希望获取的信号量被释放。

 

来源:http://lion3875.blog.sohu.com/102725871.html

 

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值