シグナルについて読んで学習しているときに、特定の方法でシグナルを使用するプログラムを見つけました。私はそれを理解しようとしましたが、コードのすべての部分が他の部分とどのように相互作用するかはわかりません。
以下は上記のコードで、問題がある箇所にコメントを追加しました。
#include <dirent.h>
#include <errno.h>
#include <fcntl.h>
#include <netinet/in.h>
#include <signal.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/socket.h>
#include <sys/stat.h>
#include <sys/types.h>
#include <sys/wait.h>
#include <unistd.h>
#define CP 5
static volatile int curprocs =0; ;
static void die() {
exit(EXIT_FAILURE);
}
static void chldhandler() {
int e = errno;
// Why do we use waitpid here? What does it do?
while(waitpid(-1, NULL, WNOHANG) > 0) {
curprocs--;
}
errno = e;
}
void do_work() {
time_t t;
srand((unsigned) time(&t));
sleep(5+ rand() % 4);
}
int main() {
struct sigaction sa = {
.sa_handler = chldhandler,
.sa_flags = SA_RESTART,
};
sigemptyset(&sa.sa_mask);
if (sigaction(SIGCHLD, &sa, NULL) == -1) {
exit(-1);
}
while(1) {
sigset_t chld, empty;
sigemptyset(&empty);
sigemptyset(&chld);
sigaddset(&chld, SIGCHLD);
// What do the following lines of code do??
sigprocmask(SIG_BLOCK, &chld, NULL);
while (curprocs >= CP) { // cap for the number of child processes
sigsuspend(&empty);
}
curprocs++;
sigprocmask(SIG_UNBLOCK, &chld, NULL);
pid_t p = fork();
if (p == -1) {
return -1;
}
if (p == 0) {
// code for the child processes to execute
do_work();
die();
} else {
// Parent process does nothing
}
}
return 0;
}
明らかに、上記のプログラムは、最大 42 個の子プロセスが動作するように意図されています。新しい子プロセスが必要なときはいつでも fork を使用し、調整しcurprocs
ます。子プロセスが終了するたびに、chldhandler() が呼び出されcurprocs
、同様に調整されます。
sigproc_mask, sigsuspend, waitpid
しかし、私は 2 つと私たちの 2 つの相互作用を理解していませんsignalsets chld, empty
。
これらの行が何をするのか、またはなぜこのように使用されるのかを誰か説明できますか?