2010-12-09 13 views
0

Ich schreibe einen TCP-Server, der sehr wie ein Chatroom funktioniert und auf diese Frage stieß.Wie drückt man zusätzliche Parameter in eine Reaper-Funktion, wenn einem Elternteil signalisiert wird, ein Kind zu töten (c)?

Wenn ein Benutzer eine Verbindung herstellt, wird ein untergeordneter Prozess für den Benutzer erstellt.
Wenn sich ein Benutzer anmeldet, speichere ich seinen Benutzernamen in eine Textdatei, online.txt
Aber wenn sich ein Benutzer abmeldet, muss ich den Benutzer von online.txt (PROBLEM) entfernen, die Eltern dann signals ein reaper() und das Kind tötet.

Meine Fragen sind:

Q1: Wie ich in zusätzliche Informationen an die Reaper (wie Benutzername, dass der Benutzer sich einloggen verwendet) drücken kann, so dass es dem Benutzer auch von online.txt entfernen? Oder gibt es eine andere bessere Methode, dies zu tun?

Q2: wo bekommt sig in reaper() seinen Wert aus? Kann ich dem Schnitter zusätzliche Parameter hinzufügen?

Q3: Könnte ich die PID des Kindes als eine Art Primärschlüssel für login.txt verwenden? Wenn ja, wie kann ich die PID des Kindes während reaper() abrufen, die vom Elternteil angerufen wird?

Der Schnitter sieht wie folgt aus:

void reaper(int sig)//where does sig come from? 
{ 
int status; 

while (waitpid(-1, &status, WNOHANG) >= 0) 
    ; 
} 

Das Signal von der Mutter verwendet sieht wie folgt aus:

(void) signal(SIGCHLD, reaper);//how can I add more parameters? 

Danke im voraus, ich hoffe auf einmal drei Fragen nicht zu ist gierig.
Jeder Einblick in eine der Fragen wird sehr geschätzt.

+1

Einem Elternteil wird signalisiert, ein Kind mit einem Schnitter zu töten ... Manchmal frage ich mich, was harmlose und unwissende Zuschauer denken, wenn sie zufällig über deine Schulter schauen, während du eine Frage wie diese eintippst? Und was wird dann mit dir passieren und wie wirst du das erklären, wenn sie die Polizei rufen ... – Secure

+0

Ich nehme an, dass ich in Kürze von diesem Forum ausgeschlossen werde. –

Antwort

2

Soweit ich aus Ihrer Frage erfassen kann, registriert der Elternprozess reaper() als Handler für SIGCHLD. Wenn es eine Anmeldung erkennt, schreibt es den Benutzernamen in eine Datei und erstellt ein Kind.

Beim Abmelden wird die reaper() - Funktion aufgerufen, weil der untergeordnete Prozess das Abmelden erkannt und somit beendet hat, oder?

Wenn ja, warum nicht nur den Server pflegen eine Datenstruktur Zuordnung PID zu Benutzername. Nehmen Sie dann den Rückgabewert von waitpid und identifizieren Sie, welcher Benutzername aus der Datei entfernt werden muss.

also zusammenfassen:

1) Nein. Ja.

2) Aus dem vom Handler empfangenen Signal.

3) Ja. Aus dem Rückgabewert von waitpid().

+0

Vielen Dank für Ihren Einblick! Die Dokumentation für waitpid() war so lang, dass ich sie nicht bis zum Rückgabewert gelesen habe. BTW, ich benutze Multi-Prozesse, weil es ein gleichzeitiger Server ist. Die Abmeldeaktion wird von einem anderen Terminal ausgeführt. –

+1

Tatsächlich konnten Sie von der Funktionsdeklaration sehen, dass der Rückgabetyp pid_t ist. Selbst wenn es sich um einen gleichzeitigen Server handelt, können Sie es mit Multithreading (yeuch) oder, noch besser, single-threaded tun. Ich bevorzuge Single-Threaded selbst. Ich wusste, dass ein Unternehmen einen Webserver mit einem einzigen Thread erstellte, aber sie betrogen, indem sie im Grunde ihren eigenen Multithreading-Code verwendeten. Wie auch immer, es ist möglich, das ganze Ding single threaded zu machen, was Vorteile hat, obwohl Multi-Prozess auch gut sein kann. Es hängt davon ab, wie genau dein Chatraum funktionieren soll. – AlastairG

1

Frage 1: Wäre es sinnvoll, einen Signalhandler für Ihren Kindprozess zu konfigurieren, um eine bestimmte Aktion auszuführen? Vielleicht wäre eine bessere Lösung jedoch, keine Datei zu verwenden, sondern ein In-Memory-Konstrukt, um zu speichern, welche Benutzer eingeloggt sind. Auf diese Weise könnte der Reaper einfach den Eintrag aus dem Speicher oder sogar den vorgeschlagenen Signal-Handler löschen.

Frage 2: Ich bin nicht vertraut mit Ihrem Betriebssystem oder Architektur, aber ich würde vermuten, dass SIGCHLD in Reaper (int sig) für den Parameterwert übergeben werden würde.

Frage 3: Das pid ist os spezifisch. Für POSIX-Typen ist es in der Regel getpid(), von unistd .. Allerdings würde ich mich fragen, ob Sie das wirklich mit einer Datei machen wollen.

Ihre Lösung kann anfällig für Race Conditions werden, wenn Sie anfangen, überall zu signalisieren ... was zu einem Sicherheitsrisiko führt.

Mitbenutzer, bitte zögern Sie nicht mich zu korrigieren. Auf der Suche nach Weisheit muss man Anweisungen annehmen.

+0

Vielen Dank für Ihren Einblick! Vor allem Q1! Ich werde mehr zu diesem Thema recherchieren! –

+1

Ich denke, er will die PID des toten Kindes, also braucht er waitpid() nicht getpid(), was nur die PID des aktuellen Prozesses zurückgibt. fork() gibt zuerst die PID des Kindes zurück. Ich sehe nicht, wie er Rassenbedingungen haben wird, wenn nur ein Prozess (der Elternteil) die Datei verwaltet. Sie haben recht, dass das Speichern der Daten im Speicher am besten ist - ich dachte, er hätte einen bestimmten Grund, eine Datei zu verwenden. – AlastairG