有没有办法在使用 fork 和 execl 创建的子进程之后在父进程中执行代码?
Is there a way to execute code in the parent process after the child, which is created using fork and execl?
我有一个父进程 play
创建一个分支并使用 execl
运行 foo
play.c
代码
#include <signal.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/wait.h>
#include <unistd.h>
int main() {
if (fork() == 0) {
execl("./foo", "", NULL);
} else {
wait(0);
write(STDOUT_FILENO, "in parent after waiting", 5);
}
printf("outside everything");
return 0;
}
foo.c
的代码
#include <signal.h>
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
void signal_handler() {
write(STDOUT_FILENO, "\nBye!\n", 6);
exit(1);
}
int main() {
struct sigaction sa;
sa.sa_handler = signal_handler;
sigaction(SIGINT, &sa, NULL);
while (1) {
printf("Wasting time...%d \n", getpid());
sleep(1);
}
return 0;
}
我的问题是,
- 为什么
wait(0)
语句后的打印语句没有执行?
- 为什么在Ctrl + C时子进程中的信号处理程序没有被触发?
您应该确保设置 struct sigaction
的 sa_flags
和 sa_mask
字段。您可以初始化它们 — struct sigaction sa = { 0 };
可能会完成这项工作。或者您可以使用 sigemptyset(&sa.sa_mask);
和 sa.sa_flags = 0;
来赋值。或者您可以将它们设置为某个 non-zero 值。不设置 sa_flags
意味着您不知道您请求的是什么操作。您还需要 play.c
中的信号处理程序。你需要在fork()
之前忽略SIGINT
,然后在子re-enable执行foo
之前发出信号。 parent 中的 write()
打印不多;它可能曾经打印过 "\nBar!\n"
或其他内容。
这是一些工作代码。
play.c
#include <signal.h>
#include <stdio.h>
#include <stdlib.h>
#include <sys/wait.h>
#include <unistd.h>
int main(void)
{
struct sigaction sa = { 0 };
sa.sa_handler = SIG_IGN;
sigaction(SIGINT, &sa, NULL);
if (fork() == 0)
{
sa.sa_handler = SIG_DFL;
sigaction(SIGINT, &sa, NULL);
execl("./foo", "", NULL);
exit(1);
}
else
{
wait(0);
printf("in parent after waiting\n");
}
printf("outside everything\n");
return 0;
}
foo.c
#include <signal.h>
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
static void signal_handler(int signum)
{
char message[] = "\nBye (XX)\n";
message[6] = signum / 10 + '0';
message[7] = signum % 10 + '0';
write(STDOUT_FILENO, message, sizeof(message) - 1);
exit(1);
}
int main(void)
{
struct sigaction sa = { 0 };
sa.sa_handler = signal_handler;
sigaction(SIGINT, &sa, NULL);
while (1)
{
printf("Wasting time...%d \n", getpid());
sleep(1);
}
return 0;
}
示例输出
$ play
Wasting time...11383
Wasting time...11383
Wasting time...11383
Wasting time...11383
^C
Bye (02)
in parent after waiting
outside everything
$
我有一个父进程 play
创建一个分支并使用 execl
foo
play.c
#include <signal.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/wait.h>
#include <unistd.h>
int main() {
if (fork() == 0) {
execl("./foo", "", NULL);
} else {
wait(0);
write(STDOUT_FILENO, "in parent after waiting", 5);
}
printf("outside everything");
return 0;
}
foo.c
#include <signal.h>
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
void signal_handler() {
write(STDOUT_FILENO, "\nBye!\n", 6);
exit(1);
}
int main() {
struct sigaction sa;
sa.sa_handler = signal_handler;
sigaction(SIGINT, &sa, NULL);
while (1) {
printf("Wasting time...%d \n", getpid());
sleep(1);
}
return 0;
}
我的问题是,
- 为什么
wait(0)
语句后的打印语句没有执行? - 为什么在Ctrl + C时子进程中的信号处理程序没有被触发?
您应该确保设置 struct sigaction
的 sa_flags
和 sa_mask
字段。您可以初始化它们 — struct sigaction sa = { 0 };
可能会完成这项工作。或者您可以使用 sigemptyset(&sa.sa_mask);
和 sa.sa_flags = 0;
来赋值。或者您可以将它们设置为某个 non-zero 值。不设置 sa_flags
意味着您不知道您请求的是什么操作。您还需要 play.c
中的信号处理程序。你需要在fork()
之前忽略SIGINT
,然后在子re-enable执行foo
之前发出信号。 parent 中的 write()
打印不多;它可能曾经打印过 "\nBar!\n"
或其他内容。
这是一些工作代码。
play.c
#include <signal.h>
#include <stdio.h>
#include <stdlib.h>
#include <sys/wait.h>
#include <unistd.h>
int main(void)
{
struct sigaction sa = { 0 };
sa.sa_handler = SIG_IGN;
sigaction(SIGINT, &sa, NULL);
if (fork() == 0)
{
sa.sa_handler = SIG_DFL;
sigaction(SIGINT, &sa, NULL);
execl("./foo", "", NULL);
exit(1);
}
else
{
wait(0);
printf("in parent after waiting\n");
}
printf("outside everything\n");
return 0;
}
foo.c
#include <signal.h>
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
static void signal_handler(int signum)
{
char message[] = "\nBye (XX)\n";
message[6] = signum / 10 + '0';
message[7] = signum % 10 + '0';
write(STDOUT_FILENO, message, sizeof(message) - 1);
exit(1);
}
int main(void)
{
struct sigaction sa = { 0 };
sa.sa_handler = signal_handler;
sigaction(SIGINT, &sa, NULL);
while (1)
{
printf("Wasting time...%d \n", getpid());
sleep(1);
}
return 0;
}
示例输出
$ play
Wasting time...11383
Wasting time...11383
Wasting time...11383
Wasting time...11383
^C
Bye (02)
in parent after waiting
outside everything
$