Newsgroup: it.comp.os.linux.iniziare
Titolo: Fermare un programma a mano

Ok, il titolo è un po' fuorviante, ad ogni modo...
Sto facendo girare un eseguibile che:
 
1- effettua un ciclo di operazioni
2- su mio PC effettua circa 100 reiterazioni al secondo
3- ogni 1000 reiterazioni scrive su un file di output dei
   risultati
4- il numero della reiteraznione del ciclo è visualizzato a schermo
4- il tutto va avanti ad oltranza finchè non sono io ad interromperlo
 
Se si ferma a mano con ctrl-c può accadere che il file di output
non contenga tutti i dati che dovrebbe stampare.
 
In pratica se si preme ctrl-c subito dopo la N-millesima reiterazione
1000 - 2000 - ecc, c'è il rischio che l'output sia ancora aperto in
scrittura. E questo non va bene perchè della roba dovrebbe ancora essere
stampata lì sopra. Se l'output viene tagliato a metà in pratica butto
via tutte le reiterazioni fatte prima e potenzialmente anche parecchio
tempo di calcolo.
 
Sto cercando di vedere come si può evitare questo fatto. Idee:
 
1- assicurarsi di uscire solo se il file di output sia chiuso e quindi
   scritto in modo completo.
 
2- oppure fare una copia del file di output ogni volta che viene
   completata la scrittura e chiuso.
 
Ho fatto uno script bash che richiama l'eseguibile per cercare ad
esempio di intercettare tipo con TRAP il "ctrl-c" dato a mano e
invece di interrompere istantaneamente il programma, fare in modo
di attendere la fine di scrittura del file di output e quindi terminare
l'eseguibile.
 
Mentre sto scrivendo mi viene in mente anche un'altra cosa
.........
#!/bin/sh
 
eseguibile &
while [ 1 ]
  cp outputfile tmpout
  if "$(tail -n1 tmpout)" = "Ultima riga che aspetterei nell'output"
    cp tmpout copiaoutput-$(date +%Y%m%d%-%H%M)
    echo "COPIA COMPLETA"
  else
    echo "COPIA INCOMPLETA" considerare quella precedente
  fi
done
....
 
in questo modo posso verificare se c'è la copia completa prima di
dare il ctrl-c per fermare il tutto.
Fare la copia dentro il programam che gira è problematico perchè è
scritto in fortran e modificarne il sorgente in modo da aggiungere
la copia del file in out dopo la chiusura non è così immediato o
potrebbe rallentare troppo il calcolo.
 
Spero di aver dato l'idea di ciò ce mi serve...
Se non fosse così dite pure.
 
Grazie inanticipo!  :)

 rallentare troppo il calcolo.
 
Credo di non aver capito esattamente tutto il marchingegno, perchè per me 
fare la copia del file no ha senso, quindi probabilmente mi soo perso un 
pezzo.
Detto questo, invece di fare signal handling con trap dal wrapper in 
bash, perchè non metti gli handlers dentro al programma in fortran?
 
Il fortran non lo consoco, ma avendo dato un occhio a questo:
 
https://www.sharcnet.ca/help/images/4/42/Fortran_Signal_Handling.pdf
 
 
mi sembrano uguali a quelli di qualsiasi altro linguaggio.
 
Ciao
 

 Spero di aver dato l'idea di ciò che mi serve...
 
Prova con:
 
$: tuo_comando_fortran | tee /tmp/pippo
 
dopo ctrl-C il file pippo ti resta completo e ci ha /tutto/ l'output
completo duplicato, comunque venga tagliato l'originale.
 
-- 
Tanti saluti
 

Addi' 14 gen 2016, Yoda scrive:

Addirittura se ti basta monitorare puoi dare:
 
$: tuo_comando_fortran | tee -
 
e vedi tutto quello che tuo_fortran sta scrivendo.
 
-- 
Tanti saluti
 


Grazie della risposta!  :)
 
 
Il punto è che al di là del handling non so come si fà a
verificare se l'unità di scrittura sia aperta e quindi
si debba attendere oppure sia chiusa e pertanto si possa
arrestare il programma, sicuri che l'output coi risultati
non resti "tagliato a metà".
 
Non sono stato chiaro su un punto forse.
Il programma ongi 1000 reiterazioni sovrascrive lo stesso
file di output: il problema è che questa sovrascrittura è un
po' troppo lenta (perchè vengoo
 
Per vari motivi, uno tra tanti è che il programma poteva
essere pensato meglio, ad ogni modo non l'ho visionato
abbastanza nel dettaglio permettermi di dirlo. Comunque non
l'ho scritto io e lo sto analizzando.
 
La copia del file di output era un espediente, per avere
un backup dei risultati.
In quel modo anche se il programma termina a metà scrittura
i risultati della precedente scrittura sono visionabili dalla
copia-backup della stessa scrittura precedente.
Si perdeno in questo modo al massimo solo mille iterazioni,
ed è ok, perchè si tratta di 10 secondi di calcolo... poco
male insomma.
 
Faccio un esempio:
 
1 apro output.dat in scrittura
2 se sono al N-millesimo giro scrivo su output.dat
                riga per riga e mi serve tempo
3 chiudo output.dat
4 copio output.dat su backup.dat
5 riparto da 1
 
Se interrompo con ctrl-c e mi trovo ancora al punto 2,
ecco che output.dat sarà scritto solo in parte.
Però avremo a disposizione il file backup.dat che ne è
la copia relativa all'iterazione (N-1)mila.
 
Cioè se immagini che la scrittura interrotta fosse relativa
per esempio alla reiterazione numero 600'000, ecco che noi
avremmo in backup.dat i risultati realtivi all'iterazione
599'000 (cioè 1000 iterazioni prima).
 
Il programma ha la particolarità di poter essere poi riavviato
prendendo in input lo stesso file che aveva sputato fuori.
In partica output.dat può essere usato come punto di partenza
per ripartire da dove si era interrotto.
 
Non è secondo me una buona idea.. ma è stato "pensato" così.
 
Il problema del fortran è che se si fà l'handling da lì
(a parte che non lo so fare e devo leggermi quella roba
sopra... ma questo è il meno..) quale comando si associa
per fare una copia del file?
 
Ma facendo l'handling dal sorgente fortran allora si potrebbe
banalmente strutturare qualcosa del tipo:
 
1- intercetta il "SIGTERM" o quel che è e associagli quanto segue
a- finisci la scrittura dell'output
b- chiudi all'unità di scrittura
c- esci dal loop
d- termina il programma
 
Può avere senso ti/vi pare?
Il problema è come realizzarlo. Non ne ho idea sinceramente.
 
Grazie mille per la risposta ogni commento è gradito!
Ciao
 
 
 
PS.
RedWiz Mi pare che una volta, se non sbaglio persona,
avessimo anche già discusso di programmazione...
"scripting" di non so più che roba fosse... Ai tempi
ero niubbo... e avevo fatto un account ad hoc per farmi
passare uno script. Era su lavabit, servizio mail che
poi è stato chiuso.


Il programma scrive in standard output della roba ad ogni reiterazione
ma scrive anche altra roba (un resoconto di risultati da tenere) su un
file di output (chiamiamolo output.dat).
 
Ho provato tee ma nel file "pippo" vedo solo quello che appare in
standard output, cioè a schermo. Non c'è traccia invece di quanto
viene scritto su output.dat.
 
Ti torna?


Se vuoi fermare un processo (proprio fermarlo senza che termini) un 
segnale di STOP puo essere una idea
Con un segnale di CONT il processo riprenderà l'esecuzione.
 
Con il comando kill si possono lanciare segnali.
 

 #!/bin/sh
handler()
{
while [ "$(pidof $PID)" ]
done
 
}
 
 
eseguibile &
while [ 1 ]
   # cp outputfile tmpout
   cp outputfile tmpout &
 
   PID=$!
   trap handler SIGINT
   if "$(tail -n1 tmpout)" = "Ultima riga che aspetterei nell'output"
     cp tmpout copiaoutput-$(date +%Y%m%d%-%H%M)
done
 
 
Se fai ctrl C puoi fare la trap handler SIGINT
 
In questo modo forse rallenti troppo, non mi è chiaro se salvi i dati o 
se perdi comunque qualcosa nell'elaborazione di eseguibile & nel frattempo.
 
ciao e scusa se ho toppato
 

    trap handler SIGINT
 
      in realtà credo che dovresti essere sicuro che il file sia stato
      copiato prima di tornare al while, forse, potresti rimuovere tmpout
      e fare la copia di outputfile solo se tmpout non esiste se esiste
      esegui l'elaborazione di questo if e poi cancelli.


 lavabit, servizio mail che poi è stato chiuso.
 
Così su due piedi non ricordo, ma tutto puo' essere!
 

 Così su due piedi non ricordo, ma tutto puo' essere!
 
Jhnnny Newbie  ;)
Come vedi sono ancora abbastanza niubbo in materia!  :D

 
 
Ribadisco che non conosco fortran, ed è molto curioso come sia tu a ad 
associare un numero al descriptor del file, invece di fartelo tornare 
dalla open, ma tant'è.
Sì, ad occhio il descrittore è quel 71, ma a sto punto ti direi di andare 
a chiedere su un gruppo/forum dedicato al linguaggio, prima di far 
cappelle.
 
 
Ciao
 
 
 


Certo, hai ragione...
detto questo mi sà che quel numero è una cosa convenzionale del linguaggio
e rappresenta la "UNIT" su cui scrivere o da cui leggere.
 
Ad esempio write(6,*) scrive a video, cioè lo standard output.
read(5,*) invece è lo stin cioè legge quello che scrivi da tastiera.
Nel fortran moderno si può ommettere e scrivere write(*,*) e read(*,*)
e fa la stessa cosa.
Per l'i/o su file sei tu ad associare una "unit" al file su cui vou
scrivere o da cui vuoi leggere. Se scrivi su un file senza fare
precedere dalla direttiva open(unit ecc) la scrittura mi pare non
avvenga. È un po' di tempo anch'io che non faccio ste cose...
 
Grazie ad ogni modo!  :)


Non posso averne la minima idea, tee legge lo stin e lo butta: o in un
file o in stdout. Ad esempio con:
$: ping 127.0.0.1 | tee -
viene scritta a video due volte ogni riga.
 
Ma scusa se quel tuo_fortran scrive anche su file, tu puoi dare il
comando di copia, da un'altra console o terminale, e solo dopo dai
ctrl-C, no? non e' l'uovo di Colombo? guarda che poi tra l'altro puoi
anche automatizzarli entrambi (tee + copia), i segnali SIG da inviare da
script al posto di ctrl-C te li stanno scrivendo in risposta gli altri,
ho intravisto.
 
 
-- 
Tanti saluti
 

 ho intravisto.
 
Ciò che viene scritto a video non mi interessa, lo posso buttare.
anzi tee forse mi rallenta anche un po' dovendo scrivere su disco
(cioè su file).
 
Riguardo l'uovo di Colombo ;) ecco infatti ciò che faccio a mano:
 
---
cp output.dat results-$(date %Y%M%-%d-%H%M)
less backup.dat
verifico "a mano" che i nuovi risultati ci siano tutti
 
se c'è tutto ---> kill dell'eseguibile
se è stato copiato mentre veniva scritto e manca della roba
                            ---> riprovo il cp e riverifico
---
 
Se fosse possibile però preferirei sostituire la soluzione
con copia di backup ma dovrei mettere le mani sul sorgente
mi pare di aver capito e possibilmente volevo evitarlo.
 
Grazie mille delle risposte comunque.
Proverò a vedere su qualche forum più specifico sulla
programmazione in fortran, se conoscete qualche forum
dove trattano l'argomento, possibilmente in italiano
sono tutt'orecchi.
 
Grazie ancora!  :)


impara il fortran.
e/o chiedi su un newsgroup di fortran, linux qua c'entra poco (a parte il SIGTERM).
 
Ciao Jack

 e/o chiedi su un newsgroup di fortran, linux qua c'entra poco (a parte il SIGTERM).
 
Avevo trovato anche questa roba... appena riesco cercherò
di metterla in pratica e trono a riferire.
 
https://www.sharcnet.ca/help/index.php/Signal_Handling_and_Checkpointing#Signal_Handling_in_Fortran