-
10-07-2019 - |
题
能信号量是低于0?我的意思是,说我有N = 3信号量和我称为“向下”的4倍,则N将保持0但一个过程将被阻塞?
和相同的其它方式,如果在开始的时候我打电话,可N为大于3?因为在我看来,如果N可以高于3,如果在一开始我后来打电话几次,然后我可以叫下来更多的时间比我能,从而把更多的进程中关键部分则信号灯让我
如果有人会澄清这一点对我来说,我将非常感激。
格雷格
解决方案
电话下来等于0时不应该工作。调出时,它的3不工作。 (我想的Java)。
让我再补充一些。很多人认为像(二进制)信号量的锁(即 - N = 1,因此该信号的值是0(保持)或1(未举行))。但是,这并不完全正确。锁拥有“所有权”的概念,因此它可能是“折返”。这意味着,持有锁的线程,允许调用lock()再次(有效地从0移动计数-1),因为线程已经保持该锁,并允许“重新进入”它。锁也可以是非折返。锁保持器被预期调用解锁()中的相同的次数作为锁()。
信号量没有所有权的概念,所以它们不能被重入的,虽然许多许可证作为可用可以被获取。这意味着一个线程需要当它遇到的值0,直到有人递增旗语到框。
此外,我所看到的(这是Java的),你可以增加信号量大于N,并且也有几分与所有权的事:一个信号量没有所有权的概念,因此任何人都可以给它更多的许可证。不同于螺纹,其中,每当一个线程调用解锁(),而不持有锁,这是一个错误。 (在Java中它会抛出异常)。
希望想着它有助于这种方式。
其他提示
(使用给定的Java标签java.util.concurrent.Semaphore中的术语。有些细节是实现特定的。我怀疑你的“上下”是Java信号灯的acquire()
方法,而你的“向上” release()
。)
嗯,你上次调用java.util.concurrent.Semaphore
将阻塞,直到另一个线程调用Semaphore
或您的线索被中断。
是,可以调用<=>更多次,然后向下更多次。
旗语的一些其它实施方案可能有一个“最大”的许可数,和呼叫释放超出最大会失败的想法。 Java的类<=>允许相反的情况,其中一个信号可以开始与负数的许可证,并且所有<=>通话将失败,直到已经足够<=>电话。一旦许可的数目已经成为非负,它永远不会再次变成负的。
格雷格您好考虑下面的例子:
public static void main(String [] args) throws InterruptedException {
Semaphore available = new Semaphore(1, true);
available.acquire();
System.out.println("Acquire : " +available.availablePermits());
available.release();
System.out.println("Released : " +available.availablePermits());
available.release();
System.out.println("Released : " +available.availablePermits());
available.release();
System.out.println("Released : " +available.availablePermits());
available.release();
System.out.println("Released : " +available.availablePermits());
available.acquire();
System.out.println("Acquire : " +available.availablePermits());
available.acquire();
System.out.println("Acquire : " +available.availablePermits());
available.acquire();
System.out.println("Acquire : " +available.availablePermits());
available.acquire();
System.out.println("Acquire : " +available.availablePermits());
available.acquire();
System.out.println("Acquire : " +available.availablePermits());
}
如果您看到的输出U将得到如下:
Acquire : 0
Released : 1
Released : 2
Released : 3
Released : 4
Acquire : 3
Acquire : 2
Acquire : 1
Acquire : 0
和等待回事。
因此,基本上允许将增加每一个版本,并获得将减小,直到0。 一旦它达到0时其将等待,直到释放被称为同一对象:)
上是,负值意味着你有等待信号量处理被释放。正值意味着你可以调用信号块之前获得很多倍。
您能想到这样的价值:正数意味着有许多可用资源。负值则意味着当所有资源都在此刻采取了许多实体需要的资源。当你获得一种资源,你递减值,当你释放你增加价值。如果该值仍> = 0您获取资源的减量后,否则你的实体被放入队列中。
信号量的维基百科一个很好的解释: http://en.wikipedia.org/wiki/Semaphore_(programming)
就看到N作为计数你有限的资源计数器。既然你不能拥有资源的一个负数,N仍然> = 0。如果你的可用资源变化的数量,最多N已经被改变了。我wouln't认为这是良好的作风来增加ñ没有在任何其他情况下,第一递减。
使用java.util.concurrent.Semaphore
与方法acquire()
和release()
,我认为允许将永远是>=0
。比方说,你要同步线程,以便只有1线程可以循环在里面。如果SEM是具有初始值1 Semaphore
的类型,这不会超过2个线程工作。
while(true){
sem.wait(); // wait is acquire
for(int i=0; i<=5; i++){
try {
Thread.sleep(250);
}catch (InterruptedException e) {}
System.out.println("Thread "+ threadname+ " " + i);
}
sem.signal(); // signal is release }
不过,可以实现从Java Semaphore类,使自己的类,允许这一点。
package yourpackage;
import java.util.concurrent.Semaphore;
public class SemaphoreLayer {
public Semaphore s=null;
public String name;
private int val;
public SemaphoreLayer(int i){
s=new Semaphore(i); val=i;
}
public void wait(){
try {
val--;
s.acquire();
} catch (InterruptedException e) {
System.out.println("Error signal semaphorelayer");
}}
public void signal(){
if(val<0){val++;}{
s.release();
val++;
}
}
}
现在VAL可以是负的。但是,我不知道,这是完全安全的,因为如果我们从一个线程拥有信号和来自其他等待他们试图val++
和val--
这可不好。 (这个可能性非常小,但还是老样子,他们的存在,所以如果你是编码,你必须是100%没有错误,我不推荐使用此代码)
总之,这是为什么它是更好地使用显示器的概念在java和关键字同步。