Monitoring and killing a process that runs too long

Nov 29, 2011 at 5:19pm
Dear all,

I have a very simple question: I run a process, and want to know how long it takes in order afterwards to be able to kill it if it runs too long.

I use the following code:


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
#include <unistd.h>
#include <sys/types.h>
#include <sys/wait.h>

void test(){

int pid = 0;
double lasttime=0;
 int status = 0;

 pid = fork();

if( pid == 0 ){
  system("echo HELLO");
  }
 else {
   int counter = 0;
   while (1)
     {
       counter++;
       if( counter > lasttime ) lasttime = counter;

       if (waitpid(pid, &status, 0) == pid) break;
     }
 }

 return;
}


so in principle 'lasttime' should be somehow the duration of my process. But it is always 0 when I print it out at the end...

I must be doing something wrong, but I don't see what.
Any remark would be welcome !

Cheers,
Xavier
Nov 29, 2011 at 10:52pm
First of all you cannot use this simple while loop to measure the time - what are the units?

Second of all read this: http://linux.die.net/man/2/waitpid

and this:

http://www.daniweb.com/software-development/cpp/threads/134643
Nov 30, 2011 at 9:55am

Thanks Jan, you are right, time unit would be more relevant,
I have modified it in the following way:


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
#include <iostream>
#include <unistd.h>
#include <sys/types.h>
#include <sys/wait.h>

using namespace std;

void test()
{

  int pid = 0;
  int w = -2;
  int status = 0;

  cout << "pid = " << pid << endl;

  pid = fork();

  if( pid == 0 ){
    cout << "pid Son = " << pid << endl;
    for( int i = 0; i < 100; i++ ) system("./SPheno LesHouches.in");
  }
  else {

    clock_t t1, t2;
    t1 = clock();
    cout << "Father process" << endl;
    cout << "pid father = " << pid << endl;
    cout << "t1       = " << t1 << endl;

    do {
         t2 = clock();
         float tdiff = (float)t2 - (float)t1;
         cout << "t2 = " << t2 << "  diff = " << tdiff << endl;

         w = waitpid(pid, &status, WUNTRACED | WCONTINUED);

         if (w == -1) {
           perror("waitpid");
           exit(EXIT_FAILURE);
         }

         if (WIFEXITED(status)) {
           printf("exited, status=%d\n", WEXITSTATUS(status));
         } else if (WIFSIGNALED(status)) {
           printf("killed by signal %d\n", WTERMSIG(status));
         } else if (WIFSTOPPED(status)) {
           printf("stopped by signal %d\n", WSTOPSIG(status));
         } else if (WIFCONTINUED(status)) {
           printf("continued\n");
         }
       } while (!WIFEXITED(status) && !WIFSIGNALED(status));
 
  }

 return;
}


Unfortunately I get only 1 printout of t2, the waitpid stopping the process. Is there a way to resume each time the child process ? I don't want only to wait that the child process be finished, but also to monitor the time it needs.

Regards,
Xavier
Dec 1, 2011 at 7:40am
You are on a hiding to nothing with this one.
Adding process control in to a process is seldom a good idea.

You need another level of indirection here, you should monitor the process from
outside, not inside. Then you can apply it generically to other cases.

If you just want a timeout you could use an alarm(2) call

Dec 1, 2011 at 9:45am
Hello,
I am a bit lost then, how would proceed ? Do you know an example ?
Thanks,
Dec 1, 2011 at 10:32am
I have tried this simple example

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
#include <iostream>
#include <unistd.h>
#include <sys/types.h>
#include <sys/wait.h>

using namespace std;

void test()
{
  clock_t t1, t2;
  alarm(1);  

  t1 = clock();
  cout << "Running SPheno" << endl;
  for( int i = 0; i < 1000; i++ ) system("./SPheno LesHouches.in");
  t2 = clock();

  cout << t1 << endl << t2 << endl << float(t2)-float(t1) << endl;



 return;
}


but curiously for a very long process, even if the alarm limit is set at 1 sec it still goes on.

I must be doing something wrong..
Topic archived. No new replies allowed.