Race Condition mittels Semaphore verhindern

BodyLAB

Bekanntes Mitglied
Hallo zusammen,

ich habe folgenden Pseudocode erhalten: (Es soll beantwortet werden ob eine Race Condition eintritt und wo)
Code:
public enum Action{open, close}
Action action; //global definiert

//Lichtschranke                                    //Türsteuerung
while(...) {                                    while(..) {
    if(activated())                                    if(action == Action.open)
        action = Action.open;                            door.open()
    else                                            else
        action = Acion.close;                            door.close()
}                                                }

Nun kann hierbei eine Race Condition auftreten, action ist global Definiert. Somit existiert nur ein Objekt für die Lichtschranke und die Türsteuerung. Das Datenelement wird sowohl geschrieben als auch gelesen, das würde schon eine Synchronisation nötig machen. Die Race Condition tritt hier jedoch bei beiden in der while Schleife ein. Die Lichtschranke schreibt action und zur gleichen Zeit kann es passieren das die Türsteuerung in der if Abfrage action lesen möchte. Wenn nun die Lichtschranke zu erst dran kommt und zwischenzeitlich bevor zu ende geschrieben werden konnte ein Threadwechsel passiert liest die Tür einen Falschen wert.

Das wäre erst einmal meine Antwort.

Nun geht es aber weiter und da komme ich nicht ganz mit.

Code:
public class Semaphore { //Mutex
void p() {}
void v() {}
}
...
Semaphore s = new Semaphore();
...
//Lichtschranke
s.p();
while(...) {
if(activated()) action = Action.open;
else action = Action.close;
}
s.v();

//Türsteuerung
s.p();
while(...) {
if(action == Action.open) door.open();
else door.close();
}
s.v();

Wenn ich das jetzt korrekt verstehe ist der Semaphore nicht Global Definiert. Somit hätte jede Klasse (Objekt) dann seinen eigenen Semaphore. Dann bringt diese ändern überhaupt nichts oder :D Der Semaphore würde bei s.p() runtergezählt werden, der Kritische Abschnitt betretten werden und einfach wieder verlassen werden über s.v();. Davon bekommt das jeweils andere Objekt nichts mit. Die Race Condition wäre damit nicht beseitigt.

Über sehe ich hierbei etwas? Birgt diese Semaphore Implementierung noch irgendwelche Nebeneffekte (Fehler)?

:oops:
 

BodyLAB

Bekanntes Mitglied
Schaue dir das mal an das was du machst hat mit dem Semaphore nicht viell zu tun.
Das habe ich ja auch nicht selbst gemacht.
Diese zwei oben gezeigten Code Beispiele habe ich bekommen und die Fragen sind:

Tritt im ersten Fall eine Race Condition auf. Meine Antwort befindet sich direkt drunter. Kurz um JA es tritt eine Race Condition auf.
Dann sollte es verbessert werden über die Semaphore.
Doch dabei Blicke ich eben nicht ganz durch denn wenn der Semaphore ja in der jeweiligen Klasse sich befindet bringt es nicht viel. Er müsste doch geteilt werden, also das beide Klassen Schranke wie auch Tür mit dem selben Semaphore arbeiten.

Darum geht es im Prinzip.
 

BodyLAB

Bekanntes Mitglied
So hab mir die Aufgabe geben lassen.

Gegeben ist der Prozess Lichtschranke, der fortlaufend die Lichtschranke einer elektronischen Tür überprüft. Falls die Lichtschranke auslöst, schreibt er den Befehl „open“ in die globale Variable action (bzw. „close“ wenn die Lichtschranke ungestört ist). Der Prozess Türsteuerung liest diese Variable und führt die geforderte Aktion aus. Nachfolgend sind die Steuerungen der beiden Prozesse auszugsweise aufgeführt:
Code:
public enum Action{open, close}
Action action; //global definiert

//Lichtschranke                                    //Türsteuerung
while(...) {                                    while(..) {
    if(activated())                                    if(action == Action.open)
        action = Action.open;                            door.open()
    else                                            else
        action = Acion.close;                            door.close()
}                                                }

1. Kann hierbei eine race condition auftreten? Falls ja, erklären Sie wo und wie dies passiert
2. Ein Programmierer hat versucht, die race conditions zu verhindern, indem er Semaphore in den Quellcode eingebaut hat. (Siehe Code unten) Treten jetzt immer noch race conditions auf? Erkennen Sie ein Problem, das durch das Setzen der Semaphore aufgetreten ist?

Code:
public class Semaphore { //Mutex
void p() {}
void v() {}
}
...
Semaphore s = new Semaphore();
...
//Lichtschranke                                    //Türsteuerung
s.p();                                            s.p();
while(...) {                                    while(...) {
if(activated()) action = Action.open;            if(action == Action.open) door.open();
else action = Action.close;                        else door.close();
}                                                }
s.v();                                            s.v();

Somit geht es hier nur um die zwei Fragen oben und alles andere ist reiner Pseudocode.
Ich würde eben Frage eins sowie zwei so beantworten:

1. Nun kann hierbei eine Race Condition auftreten, action ist global Definiert. Somit existiert nur ein Objekt für die Lichtschranke und die Türsteuerung. Das Datenelement wird sowohl geschrieben als auch gelesen, das würde schon eine Synchronisation nötig machen. Die Race Condition tritt hier jedoch bei beiden in der while Schleife ein. Die Lichtschranke schreibt action und zur gleichen Zeit kann es passieren das die Türsteuerung in der if Abfrage action lesen möchte. Wenn nun die Lichtschranke zu erst dran kommt und zwischenzeitlich bevor zu ende geschrieben werden konnte ein Threadwechsel passiert liest die Tür einen Falschen wert.
Bei Punkt 2 stellt sich eben die Frage wie ist das ganze Aufgebaut. Wenn wir hier von zwei Klassen Sprechen und einem geteilten Semaphore sollte es doch Funktionieren. Wenn jedoch es zwei Klassen sind und in jeder Klasse wird ein eigener Semaphore definiert klappt es wieder nicht. Hier mal so wie ich es mir vorstelle als Code Beispiel:
Java:
public class Lichts {
    
    Action action;
    
    public Lichts(Action a) {
        action = a;
    }
    
    public class Semaphore {
        void p() {}
        void v() {}
    }
    
    public static void main(String[] args) {
        ...
        Semaphore s = new Semaphore();
        ...
        s.p();
        while(...) {
            if(activated())
                action = Action.open;
            else
                action = Action.close;
        }
        s.v();
    }
}

Java:
public class Tür {
    
    Action action;
    
    public Tür(Action a) {
        action = a;
    }
    
    public class Semaphore {
        void p() {}
        void v() {}
    }
    
    public static void main(String[] args) {
        ...
        Semaphore s = new Semaphore();
        ...
        s.p();
        while(...) {
            if(action == Action.open)
                door.open();
            else door.close();
        }
        s.v();
    }
}

Dadurch hätten wir eine Globale Action Variable und die Semaphore haben nichts miteinander zu tun wodurch sie Sinnlos wären.
Der Kritische Abschnitt die Race Condition wäre nicht behoben.

So hätte ich das ganze nun verstanden. Ich kann mich auch irren, außerdem Verstehe ich eben dann auch nicht was für ein Problem jetzt entstehen würde wenn man dort Semaphore so nutzen würde?
 

Jw456

Top Contributor
Ich gehe mal davon aus das die while Schleife in der run vom Thread ist.
Und das die while fast eine endlos Schleife ist.

Wenn du vor der while Schleife s.p() machst, somit denn folge code schützt.
Du aber aufgrund der endlos Schleife nie zum wieder freigeben kommst s.v().

Hat es dann einen Sinn?

Wenn du dir das Code Beispiel der Insel anschaust wo macht er da den Schutz?
 
Zuletzt bearbeitet:

BodyLAB

Bekanntes Mitglied
Hat es dann einen Sinn?
Nein Überhaupt nicht. Weil ich auch nichts mit dieser Aufgabe Anfangen kann hab ich es hier gepostet ^.^

Also das erste was ich sehr merkwürdig finde ist, das oben steht die enum class ist Global Definiert.
Beim Semaphore steht das nicht!

Würden wir nun alles in eine Klasse Schreiben, bräuchte man diese Information nicht (vielleicht soll das nur verwirren). Stellen wir uns nun aber einmal vor es steht alles in einer Klasse. Was macht das für einen Sinn? Wenn wir davon ausgehen das beide while Schleifen Endlos laufen macht das ganze null Sinn oder irre ich mich?
Hier mal skiziert:
Java:
public class Main {
    
    Action action;
    
    public Main(Action a) {
        action = a; //könnte man ja nun auch einfach in der main Methode erstellen ich lass es mal hier stehen
    }
    
    public class Semaphore {
        void p() {}
        void v() {}
    }
    
    public static void main(String[] args) {
        ...
        Semaphore s = new Semaphore();
        ...
        s.p();
        while(...) { //sicherlich eine Endlosschleife
            if(action == Action.open)
                door.open();
            else door.close();
        }
        s.v();
        
        s.p();
        while(...) {//sicherlich eine Endlosschleife
            if(action == Action.open) door.open;
            else door.close();
        }
        s.v();
    }
}

Selbst wenn wir es in einen Thread schreiben und in die run Methode, würde es ja nicht anders aussehen nur der Aufruf wäre ein anderer.

Das bedeutet, so wird es sicherlich nicht gedacht sein.

Wir haben also sicherlich zwei Klassen. Vielleicht geht es aber auch gar nicht so sehr darum wie die Klassen auszusehen hätten sondern nur um die Grund Problematik.

Die Grund Problematik wäre ja das eine Race Condition existiert. Wenn wir nun einen einzigen Semaphore nutzen hätten wir keine Änderung in meinen Augen. Es steht dort noch das wir uns damit eher ein Problem einkaufen doch das sehe ich derzeit leider nicht! (vielleicht ja jemand von euch).

Müsste man diese Problematik verbessern könnte man ja "einfach" Argumentieren man nimmt statt einen Mutex eben zwei und überkreuzt diese (weiß nicht ob man das so nennt :D).

Code:
public class Semaphore { //Mutex
void p() {}
void v() {}
}
...
Semaphore s1 = new Semaphore(1);
Semaphore s2 = new Semaphore(0);
...
//Lichtschranke                                    //Türsteuerung
s1.p();                                            s2.p();
while(...) {                                    while(...) {
if(activated()) action = Action.open;            if(action == Action.open) door.open();
else action = Action.close;                        else door.close();
}                                                }
s2.v();                                            s1.v();

Damit wäre in diesem Code Beispiel doch das Problem beseitigt. Vermutlich denken wir derzeit zu viel wie man es "wirklich" Lösen würde?

Könnte das so sein?
 

Jw456

Top Contributor
Bei dem Ursprungs Code. Würde nur ein thread arbeiten. Der erste macht die Schranke zu vor der while arbeitet dann.
Der zweite wartet vor der while vergebens.
 

BodyLAB

Bekanntes Mitglied
Nein wenn dann muss s.p() und s.v() in die while nicht außerhalb.
:eek: stimmt.
Hätten wir dann oben wenn es nur ein Mutex gibt und dieser Außerhalb der while Schleife geschrieben wird nicht sogar eine Sperre? So gesehen gewinnt der erste der durch den Mutex kommt und dieser läuft endlos in seiner While Schleife rum. Der andere verhungert doch dann. ODER?
 

Jw456

Top Contributor
:eek: stimmt.
Hätten wir dann oben wenn es nur ein Mutex gibt und dieser Außerhalb der while Schleife geschrieben wird nicht sogar eine Sperre? So gesehen gewinnt der erste der durch den Mutex kommt und dieser läuft endlos in seiner While Schleife rum. Der andere verhungert doch dann. ODER?
Habe ich doch schon gesagt.
 

BodyLAB

Bekanntes Mitglied
Ach so, ja denn habe ich ja gelesen und jetzt erst die Aufgabe an sich verstanden. So macht es ja schon "Sinn" :)
Danke nochmals :cool:
 
Ähnliche Java Themen
  Titel Forum Antworten Datum
hdi Hilfe, was is da los (Race Condition?) Java Basics - Anfänger-Themen 2
G probleme, threads zu snychronisieren (race condition) Java Basics - Anfänger-Themen 4
U Race Condition Java Basics - Anfänger-Themen 25
H Datentypen "String" == "String" aber Condition greift nicht?!?!?! Java Basics - Anfänger-Themen 11
S Condition Problem Java Basics - Anfänger-Themen 6
N Threads über Condition synchronisierern Java Basics - Anfänger-Themen 2
L Sessionvariable für Condition in JSP benutzen Java Basics - Anfänger-Themen 3
M Anzahl Kommandozeilenparamter mittels Methode Java Basics - Anfänger-Themen 11
B Dom Manipulationen mittels Java Java Basics - Anfänger-Themen 8
ravenz Schleife mit for über String Array „zahlen“und prüfen ob Wert „a“ oder „b“ oder „c“ entspricht (mittels || ) Java Basics - Anfänger-Themen 4
D Gerade oder ungerade Zahl mittels Methoden Java Basics - Anfänger-Themen 13
Fats Waller Compiler-Fehler Kann ich einen String und die Summe zweier Char Werte mittels der println Anweisung ausgeben Java Basics - Anfänger-Themen 4
P9cman Vokale in einem String überprüfen mittels Rekursion Java Basics - Anfänger-Themen 8
Poppigescorn Arrayliste Mittels Scanner erweitern Java Basics - Anfänger-Themen 6
TimoN11 Quadratwurzel mittels Funktionswert der Quadratfunktion Java Basics - Anfänger-Themen 9
Khaled-Abo Ziffern unterscheiden mittels einer For-Schleife Java Basics - Anfänger-Themen 6
L Quadratwurzelrechnung mittels Heron-Verfahren Java Basics - Anfänger-Themen 6
P Klassenübergreifende Ausgabe mittels "getter" nicht möglich Java Basics - Anfänger-Themen 21
M Objekte mittels equals vergleichen Java Basics - Anfänger-Themen 14
I csv auslesen, mittels List Java Basics - Anfänger-Themen 18
V Erste Schritte Potenzen b^n mittels Schleife ermitteln Java Basics - Anfänger-Themen 7
S XML mittels HTTP Get Anfrage Java Basics - Anfänger-Themen 4
W Teilstring durch Teilstring mittels StringBuilder ersetzen Java Basics - Anfänger-Themen 7
P Liste mit Lücken mittels Filter aggregieren Java Basics - Anfänger-Themen 7
M Methoden Mittelwert rationaler Zahlen mittels Methode Java Basics - Anfänger-Themen 4
P Klassen In einer Autoklasse das Objekt Auto mittels Collection Speichern Java Basics - Anfänger-Themen 4
M Fibonacci rekursiv mittels Cache Java Basics - Anfänger-Themen 17
K Methoden Zahlensysteme umwandeln mittels Rekursion Java Basics - Anfänger-Themen 5
S int-Array mittels Arrays.sort() in einer Schleife sortieren. Java Basics - Anfänger-Themen 2
A JavaScript Object Notation einbinden mittels Maven Java Basics - Anfänger-Themen 7
L Liste mittels Stack implementieren Java Basics - Anfänger-Themen 0
J OOP GUI-Einstellungen mittels Preferences Java Basics - Anfänger-Themen 0
J ComboBox mittels neuer Methode befüllen Java Basics - Anfänger-Themen 3
A Android-Lib: Sourcecode Generator mittels Annotation Processing Java Basics - Anfänger-Themen 0
W Erste Schritte Exceltabelle in Datenbank übertragen mittels XDEV Java Basics - Anfänger-Themen 7
L Histogram mittels Schleifen und Arrays Java Basics - Anfänger-Themen 9
S Klassen Tiefe Kopie mittels Kopierkonstruktor Java Basics - Anfänger-Themen 6
S Columnindex mittels Columnname herrausfinden Java Basics - Anfänger-Themen 6
M Explorer oeffnen mittels java.awt.Desktop Java Basics - Anfänger-Themen 18
Dogge URL-Ausgabe/Verarbeitungsproblem mittels einer Applikation Java Basics - Anfänger-Themen 2
H Methoden Array aus Punkten erzeugen, mittels Punkt-Klasse Java Basics - Anfänger-Themen 5
S Dateien mittels Path(s) kopieren und umbenennen. Java Basics - Anfänger-Themen 4
C Dynamische (AJAX) Inhalte einer Webseite mittels Java auslesen Java Basics - Anfänger-Themen 2
N Mittels For Schleife Klasse erzeugen Java Basics - Anfänger-Themen 32
B Abfrage mittels Variable vereinfachen Java Basics - Anfänger-Themen 6
D Klassen Zeichnen von Figuren mittels vorgegebener Klasse Java Basics - Anfänger-Themen 3
P Collatz-Folge mittels indirekter Rekursion Java Basics - Anfänger-Themen 8
J Wurzelberechnung (mittels Newton) Java Basics - Anfänger-Themen 14
B Lotto mittels TreeSet Java Basics - Anfänger-Themen 3
C Vererbung "extends" umgehen mittels Objekterzeugung?! Java Basics - Anfänger-Themen 29
A String mittels RegEx filtern Java Basics - Anfänger-Themen 13
U E-Mails mittels Java senden. Java Basics - Anfänger-Themen 2
J Aufruf von Funktionen in *.jar mittels Eclipse Java Basics - Anfänger-Themen 4
E PHP Datei mittels Java aufrufen? Java Basics - Anfänger-Themen 3
P Collections Queue mittels ArrayList Java Basics - Anfänger-Themen 2
F Substring mittels RegEx ermitteln/ersetzen? Java Basics - Anfänger-Themen 2
R 3 Datumsangaben sortieren mittels Switch Java Basics - Anfänger-Themen 9
J Arraylänge mittels "Array.getLength" bestimmen!? Java Basics - Anfänger-Themen 3
I Ascii Bild mittels Scanner einlesen Java Basics - Anfänger-Themen 9
K OOP Datenkapselung mittels private - length Attribut bei Array Java Basics - Anfänger-Themen 3
M Delphi-DLL mittels JNI aufrufen Java Basics - Anfänger-Themen 11
H .jar Consolenprogramm mittels Doppelklick starten Java Basics - Anfänger-Themen 2
S SQL Anweisung mittels PreparedStatement Java Basics - Anfänger-Themen 15
M Additions mittels Rekursion Java Basics - Anfänger-Themen 15
E Array mittels Methode umgekehrt ausgeben Java Basics - Anfänger-Themen 6
Binary.Coder Skalarprodukt mittels long und binärzahlen Java Basics - Anfänger-Themen 5
M Auf Java (Desktop) Applikation mittels Webseite zugreifen Java Basics - Anfänger-Themen 6
W Suche nach strings zwischen eckigen Klammern mittels regulärer Ausdrücke Java Basics - Anfänger-Themen 3
Gonzalez Eingabe des Benutzers mittels readLine()-Methode. Klappt in meinem Beispiel nicht! Java Basics - Anfänger-Themen 7
R JTextField mittels JButton in Konsole ausgeben Java Basics - Anfänger-Themen 2
Z Terminkalender mittels Klassen und Feldern Java Basics - Anfänger-Themen 2
M Benutzer löschen mittels Netbeans Java Basics - Anfänger-Themen 4
I (fremde) IP mittels Applet auslesen Java Basics - Anfänger-Themen 6
G Mittels Runtime prüfen ob ein Programm läuft? Java Basics - Anfänger-Themen 18
M MenuShortcut nur mittels Shift+Taste Java Basics - Anfänger-Themen 3
N einbinden von anderen klassen mittels import Java Basics - Anfänger-Themen 2
M Datei speichern mittels InputStream Java Basics - Anfänger-Themen 13
G Navigations mittels Applet Java Basics - Anfänger-Themen 3
M ArrayList sortieren mittels Comparator Java Basics - Anfänger-Themen 10
C Lösung einer Aufgabe mittels Iteration und Rekursion Java Basics - Anfänger-Themen 12
T Zugriff auf umgebendes Objekt mittels Objekt innerer Klasse Java Basics - Anfänger-Themen 2
K Java-Programm mittels Shell-Skript aufrufen Java Basics - Anfänger-Themen 3
L Vorhandene SVG mittels Batik anzeigen Java Basics - Anfänger-Themen 8
K Datum mittels Thread aktualisieren Java Basics - Anfänger-Themen 6
G mittels Parameter Variable identifizieren Java Basics - Anfänger-Themen 6
T Zeitmesser mittels Threads implementieren Java Basics - Anfänger-Themen 16
V Mittels Java Pfeile erstellen Java Basics - Anfänger-Themen 3
J mehrere JCheckBoxen mittels Schleife abfragen Java Basics - Anfänger-Themen 13
T Erstellen eines Steuerprogramms mittels if-anweisungen Java Basics - Anfänger-Themen 10
R Vector nach Teilzeichenkette durchsuchen (mittels regex) Java Basics - Anfänger-Themen 5
G Mittels RegExp "Variablen" extrahieren Java Basics - Anfänger-Themen 4
T Fernsteuerung mittels Sockets (Architektur okay?) Java Basics - Anfänger-Themen 4
H Subtraktion mittels Negierung auf Addition zurückführen Java Basics - Anfänger-Themen 4
G Objekte mittels Schleife anlegen und ansprechen Java Basics - Anfänger-Themen 8
A Programm mittels Konsole öffnen Java Basics - Anfänger-Themen 12
B Querverweise auf eine Hilfedatei mittels ?Button? Java Basics - Anfänger-Themen 4
E Methodenaufruf mittels variable? kA Java Basics - Anfänger-Themen 5
P Collection Vector speichern mittels Serialisierung? Java Basics - Anfänger-Themen 2

Ähnliche Java Themen

Neue Themen


Oben