计数和二进制信号量的区别是什么?
我在某处看到的是,两者都可以控制请求资源的N个进程。两者都有taken状态和Free状态。
二进制信号量和计数信号量可以保护多少资源有限制吗?
两者都只允许一个进程一次使用一个资源...
还有其他区别吗?上述属性是否正确?
发布于 2012-06-05 21:43:30
实际上,这两种类型都用于同步对共享资源的访问,无论尝试访问的实体是进程还是线程。
区别如下:
二进制信号量是二进制的,它们只能有两个值;一个表示进程/线程在临界区(访问共享资源的代码),其他进程/线程应该等待,另一个表示临界区是空闲的。
另一方面,计数信号量接受两个以上的值,它们可以有任何你想要的值。它们取的最大值X允许X个进程/线程同时访问共享资源。
有关更多信息,请查看此链接。
http://www.chibios.org/dokuwiki/doku.php?id=chibios:articles:semaphores_mutexes
编辑
计数信号量可以接受的最大值是您希望同时允许进入临界区的进程数。
同样,您可能会遇到这样一种情况:您希望排除某个资源,但是您知道该资源可以被最大数量的进程(比如X)访问,因此您使用值X设置了一个计数信号量。
这将允许X进程同时访问该资源;然而,进程X+1必须等待,直到临界区中的一个进程退出。
发布于 2014-03-23 04:13:45
构建并发程序有两个基本概念--同步和互斥。我们将看到这两种类型的锁(信号量通常是一种锁定机制)如何帮助我们实现同步和互斥。
信号量有两个部分:一个计数器和一个等待访问特定资源的任务列表。信号量执行两个操作:等待(P)这类似于获取锁,释放(V)类似于释放锁-这是人们可以对信号量执行的仅有的两个操作。在二进制信号量中,计数器在逻辑上介于0和1之间。您可以将其视为类似于具有两个值的锁:打开/关闭。一个计数信号量有多个count值。
重要的是要理解的是,信号量计数器跟踪不需要阻塞的任务的数量,即它们可以取得进展。任务阻塞,并且仅当计数器为零时才将其自身添加到信号量的列表中。因此,如果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);
}在上面的示例中,只有在B1完成执行之后,B2才能执行。假设线程A先执行-Let to sem.P(),然后等待,因为计数器是0(关闭)。线程B出现了,完成了B1,然后释放了线程A-然后线程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不能同时进入临界区。因此,每个线程都使用相同的信号量来为其两个临界区提供互斥。现在,有没有可能拥有更大的并发性?取决于临界区。(想一想如何使用信号量来实现互斥。提示:我是否一定只需要使用一个信号量?)
计数信号量:具有多个值的信号量。让我们来看看这是什么意思--一个有多个值的锁?所以open、closed和...hmm。互斥或同步中的多级锁有什么用?
让我们取两者中较简单的一个:
使用计数信号量的同步:假设你有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。它们是以什么顺序释放的?取决于信号量列表的实现。可以是先进先出,可以基于某种特定的优先级,等等(注意:如果您希望t1和t2以某种特定的顺序执行,并且您不知道信号量的实现,请考虑如何安排P和V;s )
(了解:如果V的数量大于P的数量,会发生什么?)
使用计数信号量的互斥:我希望你为此构建自己的伪代码(让你更好地理解事情!)-但基本的概念是:计数器=N的计数信号量允许N个任务自由进入临界区。这意味着您有N个任务(或者线程,如果您愿意)进入临界区,但是N+1th任务被阻塞(出现在我们最喜欢的阻塞任务列表中),并且只有当某人V至少有一次信号量时才允许通过。所以信号量计数器,而不是在0和1之间摇摆,现在在0和N之间,允许N个任务自由进入和退出,不会阻塞任何人!
现在,你为什么需要这样一个奇怪的锁?互斥的全部意义不就是不让多个人访问一个资源吗?想。(Hint...You在您的计算机中并不总是只有一个驱动器,您是否...?)
思考一下:互斥是通过单独使用计数信号量来实现的吗?如果您有10个资源实例,并且有10个线程进入(通过计数信号量)并尝试使用第一个实例,该怎么办?
发布于 2017-04-25 14:54:27
计数和二进制信号量之间最基本的区别是:
队列计数信号量:结构S{ int s; q;}
现在使用计数信号量进程一旦获得CS(临界区),现在必须等待其他进程获得CS,因此不是单个进程。每个进程都有一个CS的机会。
https://stackoverflow.com/questions/10898022
复制相似问题