私はCでネットワークインタフェースをリッスンし、クライアントを受け入れるシンプルなサーバー/クライアントプログラムを実行しています。各クライアントは、フォークされたプロセスで処理されます。C:fork()子プロセスが切断されたときに親に通知します。
私が持っている目標は、クライアントが子プロセスから切断されると親プロセスに知らせることです。
現在、私のメインループは次のようになります。
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 */
それはすべてがうまく機能し、私が持っている唯一の問題は、ブロッキングaccept
コールに(おそらく)です。
上記のサーバーに接続すると、新しい子プロセスが作成され、child_processing
が呼び出されます。
私はそのクライアントとの接続を切断するときしかし、メインの親プロセスはそれについて知っていないと出力printf("[EXIT] child %d terminated\n", w);
しないんしかし、私はた後、第2のクライアントを接続したときに最初のクライアントは、メインを切断しましたループは最終的にwhile ((w = waitpid(-1, &status, WNOHANG)) > 0)
の部分を処理することができ、最初のクライアントが切断されていることを伝えます。
その後に接続と切断を行うクライアントが1つしかない場合、メインの親プロセスは、切断されたかどうかを判断できません。
クライアントが既に残っていることを親プロセスに伝える方法はありますか?
使用スレッドとしてそれらを残します。 'fork()'モデルは基本的に時代遅れです。 – EJP
@EJP、決して 'fork()'は時代遅れです。以下の回答を参照してください - スレッドでネイティブに**利用できない**ソリューションを実際に提供します。 – SergeyA