|
|||||||
|
|
|
![]() |
|
|
Strumenti |
|
|
#1 |
|
Senior Member
Iscritto dal: Jul 2002
Messaggi: 869
|
[C] Segnale SIGXCPU e somma dei tempi di cpu tra processo padre e figli.
Salve ragazzi. Avrei bisogno di una consulenza per un problemino che mi sta dando filo da torcere.
Consideriamo il codice qui sotto: Codice:
int main(){
struct rlimit limitbuf;
int i;
getrlimit(RLIMIT_CPU, &limitbuf);
limitbuf.rlim_cur = 3602;
limitbuf.rlim_max = 3700;
setrlimit(RLIMIT_CPU, &limitbuf);
if( signal(SIGXCPU,GestoreKill)==SIG_ERR ){
printf("errore di ritorno della signal (SIGXCPU).\n");
exit(0);
}
for(i=1;1<k;i++)
system("gambit <input_file | head-1 >output_file");
................
................
return 1;
}
P.S. Ovviamente usare un alarm non va bene perchè quella conterebbe il tempo di sistema e non quello di cpu. P.P.S. Un'alternativa alla system potrebbe essere quella di usare una fork per creare un processo figlio e tramite una execl inviare il comando shell ma non so se in questo modo il tempo di cpu usato dal padre e dal figlio venga sommato e soprattutto ho avuto vari problemi nell'utilizzare la execl per lanciare il comando shell. Idee?
__________________
Notebook: MBP 15 i7 Retina, (Mid 2014) |
|
|
|
|
|
#2 |
|
Senior Member
Iscritto dal: Apr 2000
Città: Roma
Messaggi: 15625
|
L'utilizzo di RLIMIT_CPU è coerente con quello che deve fare, purtroppo. Non oso chiedere quale masochistico requisito ti impone questa misura.
La soluzione non è semplice, ma ci possiamo inventare qualcosa. Intanto ti consiglio di cambiare la system con l'implementazione esplicita, fork() + exec() + waitpid(). Ci consente un pò di flessibilità in più, ad esempio ci consente di conoscere il pid del child. In un primo modo di procedere, devi conoscere dal processo parent quante risorse usa il child; possiamo procedere come top, che usa i campi utime e stime di /proc/<pid>/stat (v. man 5 proc). Il problema è che questi campi sono in jiffies, secondo la documentazione, e non c'è un modo per capire a quanto vale un jiffie (un tempo era fisso a 1/100 di secondo, oggi può variare). Un modo più raffinato è quello usato da time. Ovvero non attendere la chiusura del child tramite wait/waitpid, ma usa la wait4 (v. man wait4). Ti fornirà i tempi esatti occupati dal child, che puoi scalare dal totale (il tempo del processo corrente lo ottieni con getrusage). Ovviamente in entrambe le soluzioni devi inventarti qualcosa se vuoi beccare il termine dell'utilizzo del tempo anche mentre un child è in esecuzione. Rimane da provare getrusage(RUSAGE_CHILDREN), forse somma da solo i tempi di tutti i child.
__________________
0: or %edi, %ecx; adc %eax, (%edx); popf; je 0b-22; pop %ebx; fadds 0x56(%ecx); lds 0x56(%ebx), %esp; mov %al, %al andeqs pc, r1, #147456; blpl 0xff8dd280; ldrgtb r4, [r6, #-472]; addgt r5, r8, r3, ror #12 Ultima modifica di ilsensine : 26-03-2008 alle 23:12. |
|
|
|
|
|
#3 | |||
|
Senior Member
Iscritto dal: Jul 2002
Messaggi: 869
|
Quote:
Codice:
int main(){
int status;
double tempo_tot_figli=0, start,tempo_corrente_padre;
struct rusage risorse;
start = timer();
for(i=1;i<k;i++){
if(fork()!= 0){ // sono il padre e aspetto...
cout << "sono il padre prima wait" << endl;
wait3(&status,0,&risorse);
}
else{
//system("/usr/bin/gambit-lcp < gambit_vrp.nfg | head -1 > output_gambit_vrp.txt");
execlp("/usr/bin/gambit-lcp","gambit-lcp","<","gambit_vrp.nfg"," |","head","-1",">","output_gambit_vrp.txt",0);
}
tempo_tot_figli += risorse.ru_utime;
tempo_corrente_padre = start - timer();
if(tempo_corrente_padre + tempo_tot_figli > 3602)
exit(0);
// il padre legge dal file di output generato dal figlio...
..................
.................
}
- Il primo problema che devo risolvere riguarda la execlp. Non riesco in nessun modo a farla funzionare. Il gambit viene lanciato ma mi da errore sul file di input perchè probabilmente non gli piace il simbolo di redirezione "<". Ovviamente lo stesso identico comando lanciato tramite la system sullo stesso file di input funziona correttamente. Commetto qualche errore nell'utilizzo della execlp? - Secondo. Come da te consigliato qui: Quote:
Quote:
__________________
Notebook: MBP 15 i7 Retina, (Mid 2014) |
|||
|
|
|
|
|
#4 | |
|
Senior Member
Iscritto dal: Apr 2000
Città: Roma
Messaggi: 15625
|
Quote:
Implementare bene la cosa non è banale, in quanto prima della exec devi aprire il file di input su stdin (per emulare < gambit_vrp.nfg); il pipe su head è una complicazione ulteriore, devi fare un ulteriore fork e connettere lo stdout di gambit con lo stdin di head, e lo stdout di head sul file di uscita. Si può fare tutto, ma a questo punto mi chiedo se lasciare la semplice system() seguita da getrusage(RUSAGE_CHILDREN) possa risolvere in maniera semplice. Dovrebbe funzionare, ma fai una prova.
__________________
0: or %edi, %ecx; adc %eax, (%edx); popf; je 0b-22; pop %ebx; fadds 0x56(%ecx); lds 0x56(%ebx), %esp; mov %al, %al andeqs pc, r1, #147456; blpl 0xff8dd280; ldrgtb r4, [r6, #-472]; addgt r5, r8, r3, ror #12 Ultima modifica di ilsensine : 27-03-2008 alle 11:38. |
|
|
|
|
|
| Strumenti | |
|
|
Tutti gli orari sono GMT +1. Ora sono le: 16:56.




















