如何使用信号量实现条件变量?

时间:2011-03-19 20:28:24

标签: algorithm mutex semaphore condition-variable

前段时间我正在考虑如何相互实现各种同步原语。例如,在pthreads中,您可以获得互斥锁和条件变量,并从中可以构建信号量。

在Windows API(或至少是旧版本的Windows API)中,存在互斥锁和信号量,但没有条件变量。我认为应该可以用互斥量和信号量来构建条件变量,但对于我的生活,我只是想不出办法。

有没有人知道这样做的好结构?

3 个答案:

答案 0 :(得分:9)

这是一个paper from Microsoft Research [pdf]来处理这个问题。

答案 1 :(得分:1)

我可能在这里遗漏了一些东西,但似乎有一种更简单的方法来实现信号量和锁定条件而不是文章中描述的方式。

class Condition {
    sem_t m_sem;
    int   m_waiters;
    int   m_signals;
    pthread_mutex_t *m_mutex;
public:

    Condition(pthread_mutex_t *_mutex){
        sem_init(&this->m_sem,0,0);
        this->m_waiters = 0;
        this->m_signals = 0;
        this->m_mutex = _mutex;
    }
    ~Condition(){}
    void wait();
    void signal();
    void broadcast();
};

void Condition::wait() {
    this->m_waiters++;
    pthread_mutex_unlock(this->m_mutex);
    sem_wait(&this->m_sem);
    pthread_mutex_lock(this->m_mutex);
    this->m_waiters--;
    this->m_signals--;
}

void Condition::signal() {
    pthread_mutex_lock(this->m_mutex);
    if (this->m_waiters && (this->m_waiters > this->m_signals)) {
        sem_post(&this->m_sem);
        this->m_signals++;
    }
    pthread_mutex_unlock(this->m_mutex);
}

答案 2 :(得分:0)

实现X给定信号量的一种方法是向系统添加服务器进程,使用信号量与其进行通信,并让该进程完成实现X的所有艰苦工作。作为学术练习,这可能是作弊,但它确实可以完成工作,而且对于客户流程的不当行为或者他们的突然死亡可能会更加强大。