3.2.11.3.1.1 Wechselseitiger Ausschluss

[gesichtete Version][gesichtete Version]
Zeile 1: Zeile 1:
=Wechselseitiger Ausschluss=
=Wechselseitiger Ausschluss=
<p>
Der folgende Quellcode ist bereits aus dem Kapitel [[Kritischer Abschnitt]] bekannt:
</p>
<p id="Listing_1">
<loop_listing title="Listing 1: Beispiele für kritische und unkritische Abschnitte" description="Ein Java-Programm mit zwei Threads. Bei Thread_A wechseln sich ein unkritischer, ein kritischer und noch ein unkritischer Abschnitt ab.">
<source lang="java" line="true">
public class Beispiel_Kritischer_Abschnitt {
static int counter = 0;
public static class Thread_A extends Thread {
public void run() {
do_something();          // unkritisch
count_from_10();        // kritisch !!!
do_something_else();    // unkritisch
}
private void do_something() {
// unkritischer Abschnitt
System.out.println("Thread_A: unkritisch");
}
private void count_from_10() {
// Vorsicht: kritischer Abschnitt!
counter = 10;
counter++;
counter++;
System.out.println("A-Counter: " + counter);
}
private void do_something_else() {
// unkritischer Abschnitt
System.out.println("Thread_A: wieder unkritisch");
}
}
public static class Thread_B extends Thread {
public void run() {
System.out.println("Thread_B ist gestartet.");
counter = 20;
counter++;
counter++;
counter++;
counter++;
counter++;
counter++;
System.out.println("B-Counter: " + counter);
}
}
public static void main(String[] args) {
Thread a = new Thread_A();
Thread b = new Thread_B();
a.start();
b.start();
}
}
</source>
</loop_listing>
</p>


<p>
<p>

Version vom 6. Februar 2015, 14:59 Uhr

Wechselseitiger Ausschluss

Der folgende Quellcode ist bereits aus dem Kapitel Kritischer Abschnitt bekannt:

 1 public class Beispiel_Kritischer_Abschnitt {
 2 
 3 static int counter = 0;
 4 
 5 public static class Thread_A extends Thread {
 6 	public void run() {
 7 		do_something();          // unkritisch
 8 		count_from_10();         // kritisch !!!
 9 		do_something_else();     // unkritisch
10 	}
11 	private void do_something() {
12 		// unkritischer Abschnitt
13 		System.out.println("Thread_A: unkritisch");	
14 	}
15 	private void count_from_10() {
16 		// Vorsicht: kritischer Abschnitt!
17 		counter = 10;
18 		counter++;
19 		counter++;
20 		System.out.println("A-Counter: " + counter);		
21 	}
22 	private void do_something_else() {
23 		// unkritischer Abschnitt
24 		System.out.println("Thread_A: wieder unkritisch");	
25 	}
26 }
27 	
28 public static class Thread_B extends Thread {
29 	public void run() {
30 		System.out.println("Thread_B ist gestartet.");
31 		counter = 20;
32 		counter++;
33 		counter++;
34 		counter++;
35 		counter++;
36 		counter++;
37 		counter++;
38 		System.out.println("B-Counter: " + counter);
39 	}
40 }
41 
42 public static void main(String[] args) {
43 	Thread a = new Thread_A();
44 	Thread b = new Thread_B();
45 	a.start();
46 	b.start();
47 }
48 
49 }

Möchte ein Prozess in seinen kritischen Abschnitt eintreten, so muss er zunächst die Funktion P(s) (bzw. down(s)) aufrufen. Hier wird geprüft, ob die Zählvariable des übergebenen Semaphors  s  noch einen Wert größergleich Eins (>=1) besitzt.

  • Falls ja: verringere den Wert der Zählvariablen um 1 und verlasse die Funktion wieder (der kritische Abschnitt darf also betreten werden).

  • Falls nein: Der aufrufende Prozess wird angehalten (blockiert) und in die Warteschlange des Semaphors  s  eingereiht (der kritische Abschnitt darf noch nicht betreten werden).

Am Ende der Bearbeitung eines kritischen Abschnitts muss der betreffende Prozess die Funktion V(s) (bzw. up(s)) aufrufen. Der Wert der Zählvariable des übergebenen Semaphors  s  wird um Eins erhöht, und falls sich in der Warteschlange des Semaphors ein (oder mehrere) Prozess(e) befinden, so entferne den ersten daraus und ändere seinen Zustand in bereit. Bei der nächsten Zuteilung der CPU kann dieser damit seinen kritischen Abschnitt betreten.