Mark T.: Socket, Threads verwenden

Hallo,

ich arbeite mich im Moment in Socket-Programmierung ein. Ich sehe nun 2. Stellen bei Server an denen man Threads einbauen könnten. Würde dies mal jemand überprüfen, ob das so stimmt. Bitte keine Links posten - habe schon genug. Vielen Dank!!!

Pseudo-Programmiersprache im Beispiel unten - verwende aber C++/C#

1. Möglichkeit
socket()
bind()
listen()
while(true)
{
   clientSocket = serverSocket.accept()
   StarteThread(clientSocket);
}

In jedem Thread wird nun die Client-Anfrage abgearbeitet. Es werden so viele Threads gestartet wie Anfragen von Clients ausgehen. Nach dem Abarbeiten einer Anfrage wird der zugehörige Thread geschlossen.

public void ServerThread(Socket clientSocket)
{
   clientSocket.Receive();
   clientSocket.Send();
   clientSocket.Close();
}

2. Möglichkeit
socket()
bind()
listen()
StarteThread thread1;
StarteThread thread2;
StarteThread …
StarteThread threadn;

In jedem Thread gestarteten Thread kann nun ein Client akzeptiert werden. Es werden n Threads gestartet und es können somit auch nur n Anfragen bearbeitet werden. Die n Threads sind immer gleichzeitig offen. Wird eine Anfrage von einem Thread abgearbeitet, kann dieser anschließend die nächste Anfrage abarbeiten.

public void ServerThread()
{
   while(true)
   {
      clientSocket = serverSocket.accept()
      clientSocket.Receive();
      clientSocket.Send();
      clientSocket.Close();
   }
}

  1. Hi,

    Also bei Nr. 1 handelt es sich um die Art der Implementierung, wie ich sie auch verwenden würde.

    Die zweite Möglichkeit sieht zunächst verlockend aus, das man glaubt "vorarbeiten" zu können, hat jedoch m.E. mehrere gravierende Nachteile:
    a) Starte Thread1 ... ThreadN. OK, und was passiert mit der N+1ten Anfrage?
    b) Race condition: Dieses ist meiner Meinung nach das Hauptproblem: Dadurch, dass jeder Thread einen eigenen accept beinhaltet, kann es (ohne weitere Synchronisationsmaßnahmen wie z.B. Semaphore) zu folgender Situation kommen:

    Thread1 beginnt accept (da er einen incoming request feststellt) und wird suspended BEVOR der Befehl vollendet wird.

    Thread2 stellt ebenfalls einen incoming request fest, auch er beginnt mit der Ausführung des accept Kommandos (und wird auch fertig...). Er ist also "zuständig" für diesen request (und wird wieder suspended).

    Nun darf Thread1 weiterlaufen - im besten Fall wird noch festgestellt, dass Thread2 schneller war, im mittleren Fall crasht der Thread1 mit Segfault und wenn es ganz blöd läuft, dann arbeiten beide Threads nun auf dem einen Request.

    Grüße,
    Richard