socketpair() & 在 worker socket 的 close() 之后创建新的 child 进程
socketpair() & creating new child processes after close() of worker socket
首先:这不是一个 Unix/Linux 系统。我正在使用 IBM AS/400 V7R1 (C++ 98) 并且无法访问 fork()。尽管如此,我确实有 spawnp() 来启动新的 child 进程,并且 AS/400 支持进程组的概念。
在我的系统中,我有一个 "head" 程序启动 X 数量的 children。该头在传入连接上调用 accept() 并立即通过 sendmsg() 将套接字交给 child 进程之一。 children 都坐在 recvmsg() 上。对于 head 程序,它是这样的:
rc = socketpair(AF_UNIX, SOCK_DGRAM, 0, pair_sd);
if (rc != 0) {
perror("socketpair() failed");
close(listen_sd);
exit(-1);
}
server_sd = pair_sd[0];
worker_sd = pair_sd[1];
// do some other stuff, set up arguments for spawnp()...
// ...
spawn_fdmap[0] = worker_sd;
for (int i = 0; i < numOfChildren; i++) {
pid = spawnp(spawn_argv[0], 1, spawn_fdmap, &inherit, spawn_argv, spawn_envp);
if (pid < 0) {
CERR << "errno=" << errno << ", " << strerror(errno) << endl;
CERR << "command line [";
for (int x = 0; spawn_argv[x] != 0; ++x) {
cerr << spawn_argv[x] << " ";
}
cerr << ']' << endl;
close(listen_sd);
exit(-1);
}
else {
CERR << "Child worker PID = " << pid << endl;
child_pids.push_back(pid);
}
}
// Close down the worker side of the socketpair.
close(worker_sd);
我有一个 reason/scheme 可以在初始程序启动后启动额外的 child 进程。我计划向 head 程序发送一些信号,这将导致 spawnp() 调用再次执行。 "close(worker_sd)" 让我担心。我可以在关闭工作套接字后再次调用 spawnp() 吗?毕竟,这只是一个数字。可以让 worker_sd 打开吗?
Can I call spawnp() again after I've closed the worker socket?
在该套接字上调用 close
后,文件描述符在此进程中不再有效。
您可能希望每个子进程都有一个单独的套接字对,这样来自不同子进程的消息就不会interleaved/corrupted。
我认为没有必要为每个 child 调用 socketpair(),这意味着必须在服务器端跟踪额外的套接字。我发现删除 'worker_sd' 上的 close() 允许我创建任意数量的额外 child 进程。关闭它并创建一个 child 进程会导致新的 child 在尝试从 parent 接收某些内容时死亡。我觉得这就是会发生的事情,它确实发生了。
首先:这不是一个 Unix/Linux 系统。我正在使用 IBM AS/400 V7R1 (C++ 98) 并且无法访问 fork()。尽管如此,我确实有 spawnp() 来启动新的 child 进程,并且 AS/400 支持进程组的概念。
在我的系统中,我有一个 "head" 程序启动 X 数量的 children。该头在传入连接上调用 accept() 并立即通过 sendmsg() 将套接字交给 child 进程之一。 children 都坐在 recvmsg() 上。对于 head 程序,它是这样的:
rc = socketpair(AF_UNIX, SOCK_DGRAM, 0, pair_sd);
if (rc != 0) {
perror("socketpair() failed");
close(listen_sd);
exit(-1);
}
server_sd = pair_sd[0];
worker_sd = pair_sd[1];
// do some other stuff, set up arguments for spawnp()...
// ...
spawn_fdmap[0] = worker_sd;
for (int i = 0; i < numOfChildren; i++) {
pid = spawnp(spawn_argv[0], 1, spawn_fdmap, &inherit, spawn_argv, spawn_envp);
if (pid < 0) {
CERR << "errno=" << errno << ", " << strerror(errno) << endl;
CERR << "command line [";
for (int x = 0; spawn_argv[x] != 0; ++x) {
cerr << spawn_argv[x] << " ";
}
cerr << ']' << endl;
close(listen_sd);
exit(-1);
}
else {
CERR << "Child worker PID = " << pid << endl;
child_pids.push_back(pid);
}
}
// Close down the worker side of the socketpair.
close(worker_sd);
我有一个 reason/scheme 可以在初始程序启动后启动额外的 child 进程。我计划向 head 程序发送一些信号,这将导致 spawnp() 调用再次执行。 "close(worker_sd)" 让我担心。我可以在关闭工作套接字后再次调用 spawnp() 吗?毕竟,这只是一个数字。可以让 worker_sd 打开吗?
Can I call spawnp() again after I've closed the worker socket?
在该套接字上调用 close
后,文件描述符在此进程中不再有效。
您可能希望每个子进程都有一个单独的套接字对,这样来自不同子进程的消息就不会interleaved/corrupted。
我认为没有必要为每个 child 调用 socketpair(),这意味着必须在服务器端跟踪额外的套接字。我发现删除 'worker_sd' 上的 close() 允许我创建任意数量的额外 child 进程。关闭它并创建一个 child 进程会导致新的 child 在尝试从 parent 接收某些内容时死亡。我觉得这就是会发生的事情,它确实发生了。