条件变量史上最详解

摘要

关于条件变量本人探究好久了,翻查很多博客书籍,都是说它能够弥补互斥锁不足,能够避免竞争,减少cpu的浪费。但是why? 一直没有找到自己想要的答案。最近比较理解了它。

为什么说条件变量要和互斥锁使用。

我们在生产者、消费者问题会遇到这样一种情况——消费者和生产者共同竞争互斥锁。当消费者远大于生产者时,此时若产品为0,但是每个消费者都去抢锁,抢到后发现没有产品,又释放,接着又被其他消费者抢到,又释放…而我们的生产者在旁边干着急。获取锁释放锁又涉及内核操作,由用户态进入内核态花费大量时间。
在这里插入图片描述
从图中我们看到,消费者和生产者处于竞争中,但是没有产品,他们处于盲目的竞争,而且浪费时间,我们需要一个管理人员来管理锁,如果没有产品就设置一个标识,表示没有产品,请生产者优先,各位消费者请排队等待。当生产好了,管理员设置标志,让消费者来。
这个管理员就是条件变量,这样优势就体现出来了:能够弥补互斥锁不足,能够避免竞争,减少cpu的浪费。

代码实现
 //线程同步必然离不开同步原语,而队列时同步原语的基础
 ThreadQueue {
    var queue: List of Thread;

    sleep() {
        enqueue current thread;
        put current thread to sleep;
    }

    wake() {
        if (queue not empty) {
            dequeue thread;
            wake thread;
        }
    }

    wake-all() {
        while (queue not empty)
            wake();
    }
}

/*锁的实现是通过队列实现的,当锁被使用了,就会进入队列并阻塞,
放弃对cpu的竞争*/
Lock {
    var isHeld: boolean;
    var waitQueue: ThreadQueue;

    acquire() {
        DisableInterrupts() /*单处理器通过禁用中断来避免竞争条件
        的发生,当中断禁止后,线程切换会被阻止。*/

        while (isHeld)
            waitQueue.sleep();
        isHeld = true;

        RestoreInterrupts()
    }

    release() {
        DisableInterrupts()

        isHeld = false;
        waitQueue.wake();

        RestoreInterrupts()
    }
}

//条件变量时管理员,拥有对锁的管理权,所以要将锁传递给它。同时拥有
队列管理阻塞线程。
Condition(lock) {
    var lock: Lock;
    var waitQueue: ThreadQueue;

    wait() {
        DisableInterrupts()

        lock.release()
        waitQueue.sleep() //通过条件变量阻塞
        lock.acquire()

        RestoreInterrupts()
    }

    signal() {
        DisableInterrupts()

        waitQueue.wake();

        RestoreInterrupts()
    }

    broadcast() {
        DisableInterrupts()

        waitQueue.wake-all();

        RestoreInterrupts()
    }
}

源码参考:https://people.eecs.berkeley.edu/~kubitron/courses/cs162-F06/hand-outs/synch.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值