Setrlimit non è affidabile?
Domanda
Sto cercando di usare setrlimit()
per tappare la quantità di tempo che un processo prende.Tuttavia non sembra funzionare quando faccio alcune operazioni come printf()
.
Ecco un programma di prova che illustra il problema:
#include <sys/resource.h>
#include <stdio.h>
int main(void) {
int i;
struct rlimit limit;
limit.rlim_cur = 3;
limit.rlim_max = 3; // send SIGKILL after 3 seconds
setrlimit(RLIMIT_CPU, &limit);
// doesn't get killed
for(i=0; i<1000000; i++)
printf("%d",i);
return 0;
}
.
Tuttavia se sostituisco il loop con una routine diversa come Naive Fibonacci:
int fib(int n) {
if(n<=1) return 1;
return fib(n-1)+fib(n-2);
}
int main(void) {
...
fib(100);
...
}
.
funziona perfettamente.Cosa sta succedendo qui?setrlimit()
è semplicemente inaffidabile?
Soluzione
Il limite della CPU è un limite su CPU secondi piuttosto che tempo trascorso.I secondi della CPU sono fondamentalmente quanti secondi la CPU è in uso e non è necessariamente relazionata direttamente con il tempo trascorso.
Quando si esegue la chiamata fib
, si martella la CPU in modo che il tempo trascorso e CPU siano chiusi (la maggior parte del tempo di processo viene speso utilizzando la CPU).Non è il caso quando si stampa dalla maggior parte del tempo è speso in I / O.
Allora, cosa sta succedendo nel tuo caso particolare è che il rlimit
è impostato ma non stai solo usando i tre secondi del tempo della CPU prima che il processo finisca.
Modifica del main
come segue Speaca il segnale da consegnare sul mio sistema:
.
int main(void) {
int i;
struct rlimit limit;
limit.rlim_cur = 3;
limit.rlim_max = 3; // send SIGKILL after 3 seconds
setrlimit(RLIMIT_CPU, &limit);
while (1) { // Run "forever".
for(i=0; i<100000; i++) {
printf("%d\n",i);
}
fib(30); // some CPU-intensive work.
}
return 0;
}
Quando time
che sotto Linux, vedi:
.
: (much looping).
52670
52671
52672
52673
52674
Killed
real 0m18.719s
user 0m0.944s
sys 0m2.416s
In tal caso, ci sono voluti quasi 20 secondi di tempo trascorso ma la CPU era in uso per soli 3,36 secondi (utente + sys).
Altri suggerimenti
Il rlimit è posto sul tempo della CPU, non del tempo della parete.A seconda di dove sta andando l'uscita, il programma potrebbe trascorrere la maggior parte del suo tempo in attesa del dispositivo di uscita.Mentre lo sta facendo, non consuma il tempo della CPU.Quindi il programma può funzionare più a lungo di 3 secondi, ma se si controlla il suo utilizzo della CPU (ps up $PID
e Guarda sotto TIME
) Mostrerà meno di 3 secondi utilizzato.