[fork()多次使用计时器

问题描述 投票:0回答:1

我有这段代码:

    int pidArr[128];
    int i=0;
    clock_t begin;
    double time_spent; 
    begin = clock();
    while(1) {
        time_spent = (double)(clock() - begin) / CLOCKS_PER_SEC; 
        if (time_spent>=2.0){ break; }
        pid = fork();
        if(pid == 0){
            pidArr[i] = getpid();
            i++;
        }
    }

我想fork()2秒钟来填充我的pid数组并退出循环,但没有发生,并且我的虚拟机严重崩溃。

我将不胜感激地进行修复。

c linux time fork
1个回答
0
投票

您意外地创建了一个分叉炸弹,问题在于,当计时器经过时,您应该杀死所有进程(或使用此pidarr进行任何您想做的事,然后杀死所有线程),例如此示例

#include <stdio.h>
#include <unistd.h>
#include <sys/time.h>
#include <signal.h>

// maybe there is a standard macro or something like that
// but on my machine in /proc/sys/kernel/pid_max there is 4194304
#define PID_MAX 4194304

pid_t pidarr[PID_MAX];

static void
sigalrmHandler(int sig)
{
  for(int i = 1; i <= PID_MAX; i++){
    printf("Killing %ld\n",(long)pidarr[i]);
    kill(pidarr[i],SIGKILL);
  }
}

int main(void){
  struct sigaction sa;
  struct itimerval new_timer;

  pidarr[0] = getpid();

  sigemptyset(&sa.sa_mask);
  sa.sa_flags = 0;
  sa.sa_handler = sigalrmHandler;
  if(sigaction(SIGALRM,&sa,NULL) == -1){
    perror("setting the handler");
    return 1;
  }

  new_timer.it_value.tv_sec = 2;
  new_timer.it_value.tv_usec = 0;
  new_timer.it_interval.tv_sec = 0;
  new_timer.it_interval.tv_usec = 0;

  // Create the timer
  if(setitimer(ITIMER_REAL,&new_timer,NULL) == -1){
    perror("setting the timer");
    return 1;
  }

  for(int i = 1; ;i++){
    switch(pidarr[i] = fork()){
    case -1: // ERROR
      perror("setting the timer");
      return 1;
    case 0:
      for(;;) // Waiting to die
        ;
    case 1:
      wait(NULL);
      break;
    }
  }

  return 0;
}

[我用settimer()https://www.man7.org/linux/man-pages/man3/setitimer.3p.html)来创建两个秒计时器,并用sigaction()https://www.man7.org/linux/man-pages/man2/sigaction.2.html)来投射信号,当信号到达时,我将杀死所有进程到pidarr数组中,所以< [my机器不会崩溃,如果计时器更大,我们将遇到相同的问题,因为机器在到达计时器之前会崩溃

© www.soinside.com 2019 - 2024. All rights reserved.