我有这段代码:
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数组并退出循环,但没有发生,并且我的虚拟机严重崩溃。
我将不胜感激地进行修复。
您意外地创建了一个分叉炸弹,问题在于,当计时器经过时,您应该杀死所有进程(或使用此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机器不会崩溃,如果计时器更大,我们将遇到相同的问题,因为机器在到达计时器之前会崩溃