Laden...

Multithreading Code verstehen

Erstellt von f.ritz vor 16 Jahren Letzter Beitrag vor 16 Jahren 2.519 Views
f.ritz Themenstarter:in
341 Beiträge seit 2004
vor 16 Jahren
Multithreading Code verstehen

Hallo zusammen!

Ich muss mich gerade mit einem Quellcode von einen Server auseinandersetzen und ich glaube dass da irgendwas nicht ganz richting, in Sachen Multithreading, ist:

class TrHandler
{
 private object Lock = new Object();

 public void senden(int connectionID)
 {
    lock(Lock)
        (new Thread(new ParameterizedThreadStart(waitAndSend))).Start(connectionID));
 }

 public void waitAndSend(object clientData)
 {
   Monitor.Enter(Lock);
      //tuhe was
   Monitor.Exit(Lock);
 }
}

Und wenn ich es richtig verstehe, wird durch den folgenden Code:

    
public void senden(int connectionID)
{
  lock(Lock)
        (new Thread(new ParameterizedThreadStart(waitAndSend))).Start(connectionID));
}

der ganze Server (wegen der lock(...)-Anweisung) zum Schweigen gebracht, bis die Funktion waitAndSend(..) abgearbeitet ist?

49.485 Beiträge seit 2005
vor 16 Jahren

Hallo f.ritz,

nein, nur bis der Thread erzeugt und gestartet ist.

herbivore

f.ritz Themenstarter:in
341 Beiträge seit 2004
vor 16 Jahren

Ah, ja! Jetzt verstehe ich!

Ich habe aber noch eine Frage zu diesen Thema - Wenn die Funktion waitAndSend(..) aufgerufen wird, enthält es folgenden Code:

public void waitAndSend(object clientData)
{
   int id = (int)clientData;
   Monitor.Enter(Lock);
      //Mache was mit dem Objekt id
   Monitor.Exit(Lock);
}

Kann da nicht was durcheinander, mit dem Objekt id, kommen!?!?!

1.378 Beiträge seit 2006
vor 16 Jahren

Monitor ist dafür da :Erklärung

B
1.529 Beiträge seit 2006
vor 16 Jahren

@f.ritz:
Nein, da die Methode in jedem Thread eine eigene lokale Variable id hat.

49.485 Beiträge seit 2005
vor 16 Jahren

Hallo f.ritz,

id ist ja kein Objekt sondern eine Variable. Diese Variable enthält nach der Zuweisung die Referenz, die per Parameter übergeben wurde. Ich sehe nicht, wo da was schief gehen sollte. Wichtig ist ja, die tatsächlichen Zugriffe auf das Objekt selbst zu synchronisieren. Konkurrierende Zugriffe auf die Variable id oder clientData sind ja ausgeschlossen, weil diese nur lokal existieren.

Was mich nur wundert ist, dass an der einen Stelle lock(Lock) und an der anderen Stelle Monitor.Enter(Lock) verwendet wird. Ich denke an beiden (allen) Stellen sollte lock(Lock) verwendet werden.

herbivore

B
1.529 Beiträge seit 2006
vor 16 Jahren

Diese Variable enthält nach der Zuweisung die Referenz

In diesem Fall ja nicht, da int. Daher enthält id eine eigenständige Kopie des Wertes und Synchronisation ist nicht erforderlich.

49.485 Beiträge seit 2005
vor 16 Jahren

Hallo Borg,

als ich meine Antwort geschrieben habe, stand da noch MyObject und nicht int. 🙂

herbivore

B
1.529 Beiträge seit 2006
vor 16 Jahren

Ahhh, der fiese Weg-Editier-Teufel...

f.ritz Themenstarter:in
341 Beiträge seit 2004
vor 16 Jahren

Original von herbivore
Was mich nur wundert ist, dass an der einen Stelle lock(Lock) und an der anderen Stelle Monitor.Enter(Lock) verwendet wird. Ich denke an beiden (allen) Stellen sollte lock(Lock) verwendet werden.
herbivore

Aber die Wirkung ist doch, unter dem Strich, die Gleiche? Oder?

f.ritz Themenstarter:in
341 Beiträge seit 2004
vor 16 Jahren

Original von Borg
Ahhh, der fiese Weg-Editier-Teufel...

Das war doch ein Typisches Multithreading-Problem gerade! 😉
Während ich den Beitrag editiert habe wurden zich Antworten geschrieben 😉

49.485 Beiträge seit 2005
vor 16 Jahren

Hallo f.ritz,

ja und nein:

Das lock-Schlüsselwort ruft Monitor.Enter am Anfang des Blocks und Monitor.Exit am Ende des Blocks auf.

Aber zum einen ist der Code schwerer zu verstehen, weil man ihn nur versteht, wenn man weiß, dass es so ist.

Zum anderen denke ich, dass


lock (Lock) {
   // Tue was
}

eher


Monitor.Enter (Lock);
try {
   // Tue was
}
finally {
   Monitor.Exit (Lock);
}

und nicht


Monitor.Enter (Lock);
// Tue was
Monitor.Exit (Lock);

entspricht.

herbivore