【问题标题】:How to initialise a binary semaphore in C如何在 C 中初始化二进制信号量
【发布时间】:2011-11-20 16:14:56
【问题描述】:

man page 中,似乎即使您将信号量初始化为值 1:

sem_init(&mySem, 0, 1);

通过多次调用,它仍然可以递增到大于 1 的值

sem_post(&mySem);

但在这个code example 中,评论似乎有不同的想法:

sem_init(&mutex, 0, 1);      /* initialize mutex to 1 - binary semaphore */

是否可以在 C 中初始化严格的二进制信号量?

注意:在这种情况下这样做而不是使用互斥锁的原因是 sem_post 和 sem_wait 可能被不同的线程调用。

【问题讨论】:

    标签: c linux semaphore init


    【解决方案1】:

    如果您想在 Linux 上使用严格的二进制信号量,我建议使用互斥锁和条件变量构建一个。

    struct binary_semaphore {
        pthread_mutex_t mutex;
        pthread_cond_t cvar;
        bool v;
    };
    
    void mysem_post(struct binary_semaphore *p)
    {
        pthread_mutex_lock(&p->mutex);
        if (p->v)
            abort(); // error
        p->v = true;
        pthread_cond_signal(&p->cvar);
        pthread_mutex_unlock(&p->mutex);
    }
    
    void mysem_wait(struct binary_semaphore *p)
    {
        pthread_mutex_lock(&p->mutex);
        while (!p->v)
            pthread_cond_wait(&p->cvar, &p->mutex);
        p->v = false;
        pthread_mutex_unlock(&p->mutex);
    }
    

    【讨论】:

    • mysem_wait 中的while 循环到底有什么意义?一个简单的if-statement 不会完成这项工作,因为pthread_cond_wait 会在收到信号后重新获取互斥锁,而pthread_cond_signal 只会解除阻塞等待条件的单个线程?
    • @BillDeRose:条件变量会受到虚假唤醒和被盗唤醒的影响。如果要检查条件,必须在循环中使用它们。
    • @DietrichEpp 我无法理解,假设您在调用 post 之前先调用 wait。 p->mutex 被锁定所以如果你调用 sem_post 线程将锁定在 sem_post 并且一切都将被锁定(我确定我错了,但我不明白)如果 pthread_cond_signal 解锁互斥锁,你为什么要使用附加互斥解锁
    • @Mquinteiro:阅读 pthread_cond_wait 的手册页。它在等待时解锁互斥锁。我在这里没有看到任何额外的互斥锁解锁,每次对 lock() 的调用都与对函数末尾的 unlock() 调用配对。
    • @DietrichEpp 这意味着何时发出信号并等待完成 p->mutex 再次被锁定?
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-10-07
    • 1970-01-01
    • 1970-01-01
    • 2013-11-04
    • 2016-05-09
    • 1970-01-01
    相关资源
    最近更新 更多