信号处理程序在 C 中显示混乱
signal handler showing confusion in C
我正在尝试使用信号来同步 N 个进程,然后打印出一些东西。
每个 child 进程注册一个处理程序,在捕获 SIGUSR1 时打印 "yo" 和 "hihi"。
我使用 kill(0, SIGUSR1) 来触发每个进程。由于捕获 SIGUSR1 的默认操作正在被杀死,我为主进程设置了一个 do-nothing 处理程序,以便它等待所有 child 死亡。
分叉和发送信号程序将重复 k 次,我预计它会显示 N*k 次 "yo" 和 "hihi"。但是,它没有像我预期的那样显示足够的 "yo" 和 "hihi"。 "yo"每次执行的次数都不一样
这是我的代码,感谢您的帮助!
#include <stdio.h>
#include <unistd.h>
#include <stdlib.h>
#include <sys/wait.h>
#include <time.h>
#include <signal.h>
#include <sys/time.h>
#include <string.h>
#define N 3
int pid_id[N];
void handler2 (int signum)
{
printf("hihi\n");
}
void handler (int signum)
{
signal(SIGUSR2, handler2);
printf("yo\n");
raise(SIGUSR2);
}
void handler_do_nothing (int signum)
{
;
}
void child(int process_index)
{
struct sigaction sa;
/* Register */
memset(&sa, 0, sizeof(sa));
sa.sa_handler = handler;
sigaction(SIGUSR1, &sa, NULL);
printf("I am %d.\n", getpid());
pid_id[process_index] = getpid();
sleep(1);
exit(0);
}
int main()
{
int i, k, status;
pid_t pid[N];
pid_t pid_wait;
struct sigaction sa_main;
/* Register */ /* Main process will terminate if catch SIGUSR1 by default setting*/
memset(&sa_main, 0, sizeof(sa_main));
sa_main.sa_handler = handler_do_nothing;
sigaction(SIGUSR1, &sa_main, NULL);
/* Race k times */
for (k=0;k<3;k++)
{
for (i=0;i<N;i++)
{
pid[i] = fork();
if (pid[i]==0)
{
child(i);
}
}
// sleep();
kill(0, SIGUSR1);
for (i=0;i<N;i++)
{
do
{
pid_wait = waitpid(pid[i], &status, WNOHANG);
printf("I am waiting..\n");
sleep(1);
}while(pid_wait != pid[i]);
}
}
printf("all done\n");
return 0;
}
您的子进程在有时间(即计划的执行资源)安装新信号处理程序之前收到信号。
这意味着当主程序发送 SIGUSR1
时,子进程的某些子集仍将安装 handler_do_nothing
。
如果你想等到子进程都完成设置,你需要添加一些进程间通信机制——例如子进程可以在准备就绪时向父进程发出信号。
我正在尝试使用信号来同步 N 个进程,然后打印出一些东西。 每个 child 进程注册一个处理程序,在捕获 SIGUSR1 时打印 "yo" 和 "hihi"。 我使用 kill(0, SIGUSR1) 来触发每个进程。由于捕获 SIGUSR1 的默认操作正在被杀死,我为主进程设置了一个 do-nothing 处理程序,以便它等待所有 child 死亡。
分叉和发送信号程序将重复 k 次,我预计它会显示 N*k 次 "yo" 和 "hihi"。但是,它没有像我预期的那样显示足够的 "yo" 和 "hihi"。 "yo"每次执行的次数都不一样
这是我的代码,感谢您的帮助!
#include <stdio.h>
#include <unistd.h>
#include <stdlib.h>
#include <sys/wait.h>
#include <time.h>
#include <signal.h>
#include <sys/time.h>
#include <string.h>
#define N 3
int pid_id[N];
void handler2 (int signum)
{
printf("hihi\n");
}
void handler (int signum)
{
signal(SIGUSR2, handler2);
printf("yo\n");
raise(SIGUSR2);
}
void handler_do_nothing (int signum)
{
;
}
void child(int process_index)
{
struct sigaction sa;
/* Register */
memset(&sa, 0, sizeof(sa));
sa.sa_handler = handler;
sigaction(SIGUSR1, &sa, NULL);
printf("I am %d.\n", getpid());
pid_id[process_index] = getpid();
sleep(1);
exit(0);
}
int main()
{
int i, k, status;
pid_t pid[N];
pid_t pid_wait;
struct sigaction sa_main;
/* Register */ /* Main process will terminate if catch SIGUSR1 by default setting*/
memset(&sa_main, 0, sizeof(sa_main));
sa_main.sa_handler = handler_do_nothing;
sigaction(SIGUSR1, &sa_main, NULL);
/* Race k times */
for (k=0;k<3;k++)
{
for (i=0;i<N;i++)
{
pid[i] = fork();
if (pid[i]==0)
{
child(i);
}
}
// sleep();
kill(0, SIGUSR1);
for (i=0;i<N;i++)
{
do
{
pid_wait = waitpid(pid[i], &status, WNOHANG);
printf("I am waiting..\n");
sleep(1);
}while(pid_wait != pid[i]);
}
}
printf("all done\n");
return 0;
}
您的子进程在有时间(即计划的执行资源)安装新信号处理程序之前收到信号。
这意味着当主程序发送 SIGUSR1
时,子进程的某些子集仍将安装 handler_do_nothing
。
如果你想等到子进程都完成设置,你需要添加一些进程间通信机制——例如子进程可以在准备就绪时向父进程发出信号。