带pthread的反信号量到底如何工作?

问题描述

我使用pthread和fork已有一段时间了,我对线程的工作方式,互斥体,条件,障碍和二进制信号量有一个了解,但是我无法掌握计数器信号量或他们如何工作。

我了解的是,每个进程都会进入等待状态,计数器递减,并且在信号中它会递增,但是我不明白这对进程意味着什么以及它与二进制信号量有何不同。我已经读过它并尝试观看视频,但并不能真正理解它。

所以我想知道是否有人可以用一种更易理解的方式来解释它的工作原理,或者是否有任何链接可以使他们以一种更清晰的方式解释它。任何其他有关多线程的信息或链接也将不胜感激。

解决方法

请考虑以下缓冲区处理:

struct buf {
     Mutex lock;
     int   head,tail,n;
     char  *data;
};
int get(Buf *b) {
    lock(&b->lock);
    if (b->head != b->tail) { /* buffer not empty */
        int ret = b->data[b->tail] & 0xff;
        b->tail = (b->tail + 1) % b->n;
        unlock(&b->lock);
        return ret;
     } else {
        /* do what?  if I drop the lock,how do I know when to try again */
     }
}

因此,我们添加了一个信号量:

struct buf {
     Mutex lock;
     Sem   navail,room;
     int   head,n;
     char  *data;
};

int get(Buf *b) {
    int ret;
    SemWait(&b->navail); /* now there will be one! */
    lock(&b->lock);
    assert(b->head != b->tail);
    ret = b->data[b->tail] & 0xff;
    b->tail = (b->tail + 1) % b->n;
    SemPost(&b->room);  /* now there is space */
    unlock(&b->lock);
    return ret;
}
int put(Buf *b,int c) {
    int next;
    SemWait(&b->room); /* now there will be one! */
    lock(&b->lock);
    next = (b->head + 1) % b->n;
    assert(next != b->tail);
    b->data[next] = c;
    b->head = next;
    SemPost(&b->navail);  /* now there is data */
    unlock(&b->lock);
    return ret;
}

因此,在此示例中,互斥锁保护缓冲区,头和尾的并发更新;信号量提供一种流量控制;将吸气机和推杆的数量限制为可用的数据和空间。

与所有并发事物一样,有许多种不同的方法和机制可以解决并发缓冲区访问,但这只是一种。

您要初始化 navail room 的内容是什么?

,

您可以查看信号量,例如原子(将解释该术语)无符号整数。 因为它的值为0或正值,所以每次进程或线程在信号量上等待时,如果信号量具有值,它将减小它,如果没有,它将被阻塞但不主动检查值(这样可以在运行时提高资源效率) 直到有一个值。 因此只要信号量的值不为0,等待就不会阻塞。 “原子”一词是指在多线程/处理环境中可以安全使用的值。