Ich mache ein einfaches Server/Client-Programm in C, die auf einer Netzwerkschnittstelle hört und akzeptiert Clients. Jeder Client wird in einem gegabelten Prozess behandelt.C: fork() informieren Eltern, wenn Kind Prozess trennt
Das Ziel, das ich habe, ist, den Elternprozess wissen zu lassen, sobald ein Client die Verbindung zum Kindprozess getrennt hat.
Derzeit meine Hauptschleife sieht wie folgt aus:
for (;;) {
/* 1. [network] Wait for new connection... (BLOCKING CALL) */
fd_listen[client] = accept(fd_listen[server], (struct sockaddr *)&cli_addr, &clilen);
if (fd_listen[client] < 0) {
perror("ERROR on accept");
exit(1);
}
/* 2. [process] Call socketpair */
if (socketpair(AF_LOCAL, SOCK_STREAM, 0, fd_comm) != 0) {
perror("ERROR on socketpair");
exit(1);
}
/* 3. [process] Call fork */
pid = fork();
if (pid < 0) {
perror("ERROR on fork");
exit(1);
}
/* 3.1 [process] Inside the Child */
if (pid == 0) {
printf("[child] num of clients: %d\n", num_client+1);
printf("[child] pid: %ld\n", (long) getpid());
close(fd_comm[parent]); // Close the parent socket file descriptor
close(fd_listen[server]); // Close the server socket file descriptor
// Tasks that the child process should be doing for the connected client
child_processing(fd_listen[client]);
exit(0);
}
/* 3.2 [process] Inside the Parent */
else {
num_client++;
close(fd_comm[child]); // Close the child socket file descriptor
close(fd_listen[client]); // Close the client socket file descriptor
printf("[parent] num of clients: %d\n", num_client);
while ((w = waitpid(-1, &status, WNOHANG)) > 0) {
printf("[EXIT] child %d terminated\n", w);
num_client--;
}
}
}/* end of while */
Das alles funktioniert gut, das einzige Problem, das ich habe, ist (wahrscheinlich) aufgrund der Sperrung accept
Anruf.
Wenn ich mich mit dem obigen Server verbinde, wird ein neuer untergeordneter Prozess erstellt und child_processing
wird aufgerufen.
Jedoch, wenn ich mit diesem Client trennen, der wichtigste übergeordnete Prozess nicht weiß über sie und nicht ausgeben printf("[EXIT] child %d terminated\n", w);
Aber, wenn ich mit einem zweiten Client nach der ersten Client einer Verbindung getrennt hat, die Haupt Schleife ist in der Lage, den while ((w = waitpid(-1, &status, WNOHANG)) > 0)
Teil schließlich zu verarbeiten und mir zu sagen, dass der erste Klient getrennt hat.
Wenn es nur einen Client gibt, der sich anschließend verbindet und trennt, kann mein Haupt-Elternprozess nie feststellen, ob die Verbindung getrennt wurde oder nicht.
Gibt es eine Möglichkeit, dem übergeordneten Prozess mitzuteilen, dass mein Client bereits verlassen hat?
UPDATE
Als ich einen echten Anfänger mit c bin, wäre es schön, wenn Sie ein paar kurze Ausschnitte auf Ihre Antwort geben, damit ich wirklich versteht, kann es :-)
Verwenden Threads. Das 'fork()' Modell ist im Grunde veraltet. – EJP
@EJP, auf keinen Fall ist 'fork()' veraltet. Siehe Antworten unten - sie bieten tatsächlich eine Lösung ** nicht verfügbar ** nativ mit Threads. – SergeyA