简体   繁体   English

如何使用SIGALRM终止程序

[英]How to terminate a program using SIGALRM

So basically I have 4-5 functions in my program. 所以基本上我的程序中有4-5个功能。 It is a lot of lines of codes and reading and writing from a file and it could end in an infinite loop (worse case) and I would like to terminate my program if it goes beyond lets say 20 seconds. 它由很多行代码和文件的读写操作组成,并且可能以无限循环(更糟的情况)结尾,如果超出20秒,我想终止程序。 below code is not working, my program hangs and the OS terminates it for me instead of the program terminating itself. 下面的代码不起作用,我的程序挂起,操作系统为我终止了它,而不是程序自行终止。 I think the main problem I am having is the alarm is set in the main and when the alarm time limit is reached the process is executing in another function and this is causing the program to shut without closing files and killing child processes. 我认为我遇到的主要问题是在主机中设置了警报,当达到警报时间限制时,该进程正在另一个函数中执行,这导致程序关闭而没有关闭文件并杀死子进程。 This is what I have for now: 这是我现在拥有的:

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 %d\n",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;
}

there is only a certain set of function which can be executed safely from a signal handler. 只有一组可以从信号处理程序安全执行的功能。 And exit is not one of them. exit 不是其中之一。 Neither is printf . printf也不是。

You might able to use the _exit() function instead (with underscore in front). 您可能可以改用_exit()函数(下划线在前面)。 However it will only exit the top-most process, leaving the children running. 但是,它将仅退出最顶层的进程,从而使子进程继续运行。

You can still kill everything using kill(0, signal) , as here. 您仍然可以使用kill(0, signal)杀死所有内容,如下所示。

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

Here is an example of a working poc code: 这是一个有效的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 %d\n",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 exit\n");
    return 0;
}

So after spending more than 24 hrs trying to fix this. 因此,在花费超过24小时尝试解决此问题之后。 The solution was actually simple. 解决方案实际上很简单。 Keep a global array of PID of children alive +1 for parent PID. 对于父级PID,使子级PID的全局数组保持活动+1。 before sending the kill(PID, SIGTERM) we have to mention a handler for SIGTERM which sleeps till the process is killed. 在发送kill(PID,SIGTERM)之前,我们必须提到SIGTERM的处理程序,该处理程序一直休眠直到进程被终止。 Thus a graceful exit. 因此,一个优雅的出口。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM