fork () несколько раз с таймером - PullRequest
1 голос
/ 27 мая 2020

У меня есть этот фрагмент кода:

    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 и выйти из l oop, но этого не произошло, и моя виртуальная машина cra sh плохо.

Буду признателен за любую помощь, чтобы исправить это.

1 Ответ

1 голос
/ 29 мая 2020

Вы случайно создали вилку-бомбу, проблема в том, что по истечении таймера вы должны убить все процессы (или сделать что хотите с этим 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, поэтому моя машина не будет крутить sh, если бы таймер был больше, мы бы столкнулись с той же проблемой, потому что машина взломала бы sh до достижения таймера

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...