30

计数和二进制信号量有什么区别。

我在某处看到的是,两者都可以控制 N 个请求资源的进程。两者都采取和自由状态。

二进制信号量和计数信号量可以保护多少资源是否有任何限制?

两者都只允许一个进程一次使用一个资源......

还有其他区别吗?上述属性是否正确?

4

3 回答 3

34

Actually, both types are used to synchronize access to a shared resource, whether the entity which is trying to access is a process or even a thread.

The difference is as follows:

Binary semaphores are binary, they can have two values only; one to represent that a process/thread is in the critical section(code that access the shared resource) and others should wait, the other indicating the critical section is free.

On the other hand, counting semaphores take more than two values, they can have any value you want. The max value X they take allows X process/threads to access the shared resource simultaneously.

For further information, take a look at this link.
http://www.chibios.org/dokuwiki/doku.php?id=chibios:articles:semaphores_mutexes

EDIT
The max value that a counting semaphore can take is the the number of processes you want to allow into the critical section at the same time.
Again, you might have a case where you want exclusion over a certain resource, yet you know this resource can be accessed by a max number of processes (say X), so you set a counting semaphore with the value X.

This would allow the X processes to access that resource at the same time; yet the process X+1 would have to wait till one of the processes in the critical section gets out.

于 2012-06-05T13:43:29.860 回答
8

构建并发程序有两个基本概念——同步和互斥。我们将看到这两种类型的锁(信号量更普遍地是一种锁定机制)如何帮助我们实现同步和互斥。

信号量有两部分:一个计数器和一个等待访问特定资源的任务列表。一个信号量执行两个操作:等待(P)[这就像获取一个锁],和释放(V)[类似于释放一个锁]——这是唯一可以对信号量执行的两个操作。在二进制信号量中,计数器在逻辑上介于 0 和 1 之间。您可以将其视为类似于具有两个值的锁:打开/关闭。计数信号量有多个计数值。

重要的是要了解信号量计数器跟踪不必阻塞的任务的数量,即它们可以取得进展。任务阻塞,仅当计数器为零时才将自己添加到信号量列表中。因此,如果一个任务无法进行,它会被添加到 P() 例程中的列表中,并使用 V() 例程“释放”。

现在,很明显可以看到二进制信号量如何用于解决同步和互斥问题——它们本质上是锁。

前任。同步:

thread A{
semaphore &s; //locks/semaphores are passed by reference! think about why this is so.
A(semaphore &s): s(s){} //constructor
foo(){
...
s.P();
;// some block of code B2
...
}

//thread B{
semaphore &s;
B(semaphore &s): s(s){} //constructor
foo(){
...
...
// some block of code B1
s.V();
..
}

main(){
semaphore s(0); // we start the semaphore at 0 (closed)
A a(s);
B b(s);
}

在上面的例子中,B2 只能在 B1 执行完毕后执行。假设线程 A 首先执行 - 到达 sem.P(),然后等待,因为计数器为 0(关闭)。线程 B 出现,完成 B1,然后释放线程 A - 然后完成 B2。这样我们就实现了同步。

现在让我们看一下二进制信号量的互斥:

thread mutual_ex{
semaphore &s;
mutual_ex(semaphore &s): s(s){} //constructor
foo(){
...
s.P();
//critical section
s.V();
...
...
s.P();
//critical section
s.V();
...

}

main(){
semaphore s(1);
mutual_ex m1(s);
mutual_ex m2(s);
}

互斥也很简单——m1和m2不能同时进入临界区。因此,每个线程都使用相同的信号量为其两个关键部分提供互斥。现在,是否有可能拥有更大的并发性?取决于关键部分。(想想还有什么方法可以使用信号量来实现互斥......提示:我一定只需要使用一个信号量吗?)

计数信号量:具有多个值的信号量。让我们看看这意味着什么——一个具有多个值的锁?如此开放,封闭,然后......嗯。多级锁在互斥或同步中有什么用?

让我们采取两者中更容易的一点:

使用计数信号量进行同步:假设您有 3 个任务 - #1 和 2 您希望在 3 之后执行。您将如何设计同步?

thread t1{
...
s.P();
//block of code B1

thread t2{
...
s.P();
//block of code B2

thread t3{
...
//block of code B3
s.V();
s.V();
}

因此,如果您的信号量开始关闭,请确保 t1 和 t2 阻塞,被添加到信号量列表中。然后出现所有重要的 t3,完成其业务并释放 t1 和 t2。他们以什么顺序被释放?取决于信号量列表的实现。可以是 FIFO,可以基于某些特定的优先级等。(注意:如果您希望 t1 和 t2 按特定顺序执行,并且您不知道信号量的实现,请考虑如何安排您的 P 和 V;s)

找出:如果 V 的数量大于 P 的数量会发生什么?)

使用计数信号量的互斥:我希望您为此构建自己的伪代码(让您更好地理解事物!) - 但基本概念是:counter = N 的计数信号量允许 N 个任务自由进入临界区. 这意味着您有 N 个任务(或线程,如果您愿意)进入临界区,但第 N+1 个任务被阻塞(进入我们最喜欢的阻塞任务列表),并且只有当某人 V 是信号量时才允许通过至少一次。所以信号量计数器,而不是在 0 和 1 之间摆动,现在在 0 和 N 之间移动,允许 N 个任务自由进出,没有人阻塞!

现在,你为什么需要这么奇怪的锁?互斥的全部意义不在于不允许多个人访问资源吗?思考。(提示...您的计算机中并不总是只有一个驱动器,是吗...?)

想一想:只有一个计数信号量就可以实现互斥吗?如果您有 10 个资源实例,并且有 10 个线程进入(通过计数信号量)并尝试使用第一个实例怎么办?

于 2014-03-22T20:13:45.163 回答
1

The most basic difference between counting and binary semaphore is that:

  1. Binary semaphore cannot handle Bounded wait as its just a variable that hold binary value. Counting semaphore It can handle bounded wait as it has converted a variable into a structure with a Queue.
  2. Strcuture implementation Binary semaphore: int s;

    Counting Semaphore: Struct S { int s; Queue q; }

Using the counting semaphore now process once gained the CS(Critical Section) now has to wait for the other to get the CS, so not a single process strave. Each process get a chance for CS.

于 2017-04-25T06:54:27.240 回答