C语言 如何使用SIGALRM终止程序



所以基本上我的程序中有4-5个函数。它是很多行代码以及从文件中读取和写入,它可能会以无限循环结束(更糟糕的情况(,如果它超过 20 秒,我想终止我的程序。下面的代码不起作用,我的程序挂起,操作系统为我终止它,而不是程序自行终止。我认为我遇到的主要问题是警报是在主中设置的,当达到警报时间限制时,进程正在另一个函数中执行,这导致程序关闭而不关闭文件并杀死子进程。这就是我现在所拥有的:

volatile sig_atomic_t keep_going = 1;
/* The signal handler just clears the flag and re-enables itself. */
void
catch_alarm (int sig)
{
printf("Alarm went off");
exit(EXIT_SUCCESS);
}
void function1
{}
void forkingfunction()
{
or(i=0;i<size;i++,temp++)
{
pid_t pID = vfork();
if (pID == 0)                // child
{ 
printf("nchild pid %dn",getpid());
//open some files and read and write
function1();
exit(EXIT_SUCCESS);
kill(pID,SIGKILL);
}
}
else if (pID < 0)            // failed to fork
{
perror("Failed to fork:");
}
}
void function2
{
function1();
}
int main()
{
int options
while(options){
switch (options)
{
case 1:
case 2:
}
}
signal (SIGALRM, catch_alarm);
alarm (0.1);//testing for 0.1 seconds 
function1();
return 0;
}

只有一组特定的函数可以从信号处理程序安全执行。exit不是其中之一。也不是printf.

您可以改用_exit()函数(前面带有下划线(。但是,它只会退出最顶层的进程,让孩子们运行。

你仍然可以使用kill(0, signal)杀死所有东西,就像这里一样。

void catch_alarm (int sig) {
kill(0, SIGTERM);
}

下面是一个工作 poc 代码的示例:

#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <signal.h>
void catch_alarm (int sig) {
kill (0,SIGTERM);
}
void forkingfunction()
{
int i;
for(i=0;i<4;i++,i++) {
pid_t pID = fork();
if (pID == 0) { 
sleep(5);
printf("nchild pid %dn",getpid());
exit(EXIT_SUCCESS);
}
else if (pID < 0) {
perror("Failed to fork:");
}
}
}
int main()
{
signal (SIGALRM, catch_alarm);
alarm (1);//testing for 0.1 seconds 
forkingfunction();
sleep(10);
printf("nnormal exitn");
return 0;
}

因此,在花费了超过 24 小时尝试解决此问题之后。解决方案实际上很简单。保持儿童 PID 的全局数组存活 +1 对于父 PID。在发送 kill(PID、SIGTERM(之前,我们必须提到 SIGTERM 的处理程序,它一直沉睡到进程被杀死。因此,这是一个优雅的退出。

相关内容

  • 没有找到相关文章