Frage

Kann sein das Semaphore niedriger als 0? Ich meine, sagen, ich habe eine Semaphore mit N = 3 und ich „down“ 4-mal, dann wird N bleiben 0, aber ein Prozess blockiert wird?

Und gleiche andersrum, wenn ich am Anfang aufrufen, können N höher sein als 3? Denn wie ich es sehe, wenn N größer als 3 sein kann, wenn ich am Anfang einige Male aufrufen, dann später konnte ich ich kann mehr Zeit als callen, so dass mehr Prozesse im kritischen Abschnitt setzen dann die Semaphore ermöglicht es mir, .

Wenn jemand es ein bisschen für mich klarstellen würde ich viel schätzen.

Greg

War es hilfreich?

Lösung

Der Aufruf nach unten, wenn es 0 ist nicht funktionieren sollte. Aufrufen, wenn es 3 ist funktioniert. (Ich denke an Java).

Lassen Sie mich etwas mehr hinzuzufügen. Viele Leute denken, von Schlössern wie (binär) Semaphore (dh - N = 1, so wird der Wert des Semaphor entweder 0 (gehalten) oder 1 (nicht gehalten)). Aber das ist nicht ganz richtig. Ein Schloss hat einen Begriff des „Eigentums“ so ist es „Reentry“ sein kann. Das bedeutet, dass ein Thread, der eine Sperre hält, darf Sperre () aufzurufen wieder (effektiv die Zählung von 0 bis -1 bewegt), da der Thread bereits die Sperre hält und darf es „erneut eingeben“. Sperren können auch nicht einspringenden sein. Ein Verriegelungshalterung wird erwartet Unlock () aufrufen die gleiche Anzahl von Malen wie Sperre ().

Semaphore haben keine Ahnung von Eigentum, so dass sie nicht einspringenden, obwohl so viele Genehmigungen als vorhanden sind erworben werden können. Das bedeutet, dass ein Thread blockieren muss, wenn er einen Wert von 0 trifft, bis jemand die Semaphore erhöht.

Auch in dem, was ich gesehen habe (die Java ist), können Sie die Semaphore größer als N zu erhöhen, und dass auch Art hat die mit dem Eigentum zu tun: eine Semaphore hat keine Ahnung von Eigentum so jemand ihm erlaubt geben kann . Im Gegensatz zu einem Gewinde, wobei immer dann, wenn ein Thread ruft entsperren () ohne ein Schloß zu halten, besteht darin, dass ein Fehler auf. (In Java wird es eine Ausnahme).

Hoffnung auf diese Weise darüber nachzudenken, es hilft.

Andere Tipps

(In der Terminologie von java.util.concurrent.Semaphore der Java-Tag gegeben. Einige dieser Details sind implementierungsspezifisch. Ich vermute, dass Ihre „down“ der acquire() Methode Java Semaphore der ist, und Ihr „up“ release() ist. )

Ja, der zuletzt getätigten Anruf acquire() blockiert, bis ein anderer Thread ruft release() oder Thread unterbrochen wird.

Ja, Sie können mehrmals rufen release(), dann mehrmals nach unten -. Zumindest mit java.util.concurrent.Semaphore

Einige andere Implementierungen eines Semaphore können eine Vorstellung von einer „Maximum“ Anzahl der Genehmigungen haben und einen Anruf zu lösen darüber hinaus maximal ausfallen würde. Die Java Semaphore Klasse ermöglicht eine umgekehrte Situation, wo ein Semaphore kann mit einer negativen Zahl der Genehmigungen und alle acquire() Anrufen beginnen schlagen fehl, bis es genug release() Anrufe gewesen sein. Sobald die Zahl der Genehmigungen ist nicht negativ wird, wird es nie wieder negativ werden.

Hallo Greg betrachten folgendes Beispiel:

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());
    }

Wenn Sie die Ausgabe siehe folgende u erhalten:

Acquire : 0
Released : 1
Released : 2
Released : 3
Released : 4
Acquire : 3
Acquire : 2
Acquire : 1
Acquire : 0

Und warten vor sich geht.

So erlaubt grundsätzlich auf jedem Release zu erhöhen und erwerben wird es bis 0 abnehmen. Sobald es 0 erreicht wird es warten, bis Release auf demselben Objekt aufgerufen wird :)

Ja, ein negativer Wert bedeutet, dass Sie Prozesse für die Semaphore warten freigegeben werden. Ein positiver Wert bedeutet, können Sie, dass viele Male, bevor die Semaphore Blöcke erwerben nennen.

Man könnte denken, der Wertes auf diese Weise: eine positive Zahl bedeutet, es gibt, dass viele Ressourcen zur Verfügung. Ein negativer Wert bedeutet, dass es, dass viele Unternehmen eine Ressource benötigt, wenn alle Ressourcen zur Zeit getroffen werden. Wenn Sie eine Ressource erwerben Sie den Wert verringern, wenn sie losgelassen erhöhen Sie den Wert. Wenn der Wert noch> = 0 nach der Abnahme ist die Ressource erhalten, sonst wird Ihr Unternehmen in eine Warteschlange gestellt.

Eine schöne Erklärung von Semaphore in Wikipedia: http://en.wikipedia.org/wiki/Semaphore_(programming)

Just siehe N wie der Zähler, die Ihre begrenzte Ressource zählt. Da Sie nicht eine negative Anzahl von Ressourcen haben können, bleibt N> = 0. Wenn die Anzahl der verfügbaren Ressourcen ändern, hat die maximale N auch geändert, wird. Ich wouln't es guten Stil betrachten n zu erhöhen, ohne es zuerst in jedem anderen Fall dekrementiert.

Mit java.util.concurrent.Semaphore mit Methoden acquire() und release(), ich denke, erlaubt wird immer >=0 werden. Angenommen, Sie Threads synchronisiert werden sollen, so dass nur ein Thread für Schleife innen sein kann. Wenn sem Typ Semaphore ist, den Anfangswert 1 hat, wird dies nicht länger als 2 Threads arbeiten.

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 }

Sie können jedoch die Semaphore-Klasse von Java implementieren und Ihre eigene Klasse machen, die dies ermöglicht.

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++;
    }
}

}

Jetzt kann val negativ sein. Allerdings bin ich nicht sicher, dass dies absolut sicher ist, denn wenn wir Signal von einem Thread haben und warten, von den anderen, und sie versuchen val++ und val-- so schlecht sein können. (Chancen dafür sind sehr klein, aber stil sie existieren, also, wenn Sie Codierung und Sie haben 100% kein Fehler sein, ich nicht empfehlen, diesen Code verwenden) Abschließend ist der Grund, warum es besser ist, Konzept der Monitore in Java und Schlüsselwort synchronisiert zu verwenden.

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top