View Full Version : problema nel lanciare processi in background (&)
ho un problema singolare....
devo lanciare in un dato ordine 5 processi in background....
uno di loro (il 3° per la precisione) controlla lo stdin e alla pressione di un tasto avvia determinate funzioni.
Il problema è che quando lancio in backgraund un processo, con il comando
./processoX &
a volte mi ritorna immediatamente la shell, altre volte invece non ritorna immediatamente la shell, ma occorre dare un invio...
è come se il processo non fosse ancora in bg, ma lo diventasse alla pressione di un tasto.
solitamente questo comportamento non mi crea problemi, ma al lancio del 3° processo si!!
xchè se ritorna immediatamente la shell tutto fila liscio come l'olio, ma se sono costretto a premere il tasto invio, il processo recepisce quell'invio come un tasto premuto e fa cose che non dovrebbe fare...
mi spete spiegare perchè accade???
e soprattutto come impedire che accada??
Nel caso non fossi stato sufficientemente chiaro allego un esempio:
-Caso ERRATO:
mercedes:~/privato/test> ./processo3.exe &
[4] 17443
mercedes:~/privato/test> avvio processo
caricamento in corso
caricamento eseguito correttamente
<---- qui rimango bloccato e se premo invio succede questo...
[4] + Suspended (tty input) ./processo3.exe
mercedes:~/privato/test>
vedete?? ritorno si alla shell ma intanto il processo è 'suspended' e ha eseguito il codice
-Caso CORRETTO:
mercedes:~/privato/test> ./processo3.exe &
[1] 18523
avvio processo
caricamento in corso
caricamento eseguito correttamente
mercedes:~/privato/test>
in questo caso invece mi ritorna direttamente la shell e tutto va come deve andare....
l'unica differenza che ho notato io è che nel primo caso dopo il lancio del processo viene restituito:
- il PID,
- poi la Shell,
- poi le frasi di debug e rimane in sospeso....
nel secondo caso viene restituito
- il PID,
- poi le frasi di debug
- poi la Shell,
grazie MILLE!!!
grillosoft
26-01-2008, 20:25
ho un problema singolare....
devo lanciare in un dato ordine 5 processi in background....
uno di loro (il 3° per la precisione) controlla lo stdin e alla pressione di un tasto avvia determinate funzioni.
Il problema è che quando lancio in backgraund un processo, con il comando
./processoX &
a volte mi ritorna immediatamente la shell, altre volte invece non ritorna immediatamente la shell, ma occorre dare un invio...
è come se il processo non fosse ancora in bg, ma lo diventasse alla pressione di un tasto.
solitamente questo comportamento non mi crea problemi, ma al lancio del 3° processo si!!
xchè se ritorna immediatamente la shell tutto fila liscio come l'olio, ma se sono costretto a premere il tasto invio, il processo recepisce quell'invio come un tasto premuto e fa cose che non dovrebbe fare...
mi spete spiegare perchè accade???
e soprattutto come impedire che accada??
Nel caso non fossi stato sufficientemente chiaro allego un esempio:
-Caso ERRATO:
mercedes:~/privato/test> ./processo3.exe &
[4] 17443
mercedes:~/privato/test> avvio processo
caricamento in corso
caricamento eseguito correttamente
<---- qui rimango bloccato e se premo invio succede questo...
[4] + Suspended (tty input) ./processo3.exe
mercedes:~/privato/test>
vedete?? ritorno si alla shell ma intanto il processo è 'suspended' e ha eseguito il codice
-Caso CORRETTO:
in questo caso invece mi ritorna direttamente la shell e tutto va come deve andare....
l'unica differenza che ho notato io è che nel primo caso dopo il lancio del processo viene restituito:
- il PID,
- poi la Shell,
- poi le frasi di debug e rimane in sospeso....
nel secondo caso viene restituito
- il PID,
- poi le frasi di debug
- poi la Shell,
grazie MILLE!!!
prova anziche eseguire i comandi con ./ prova con sh e vedi se il problema persiste
ciao grillosoft,
ho provato a lanciare i processi con sh, ma in questo modo TUTTI i processi mi restituiscono un errore..
sh processo3.exe ----> processo3.exe: 1: Syntax error: "(" unexpected
poi ho provato a lanciare solo sh, e lanciare i comando da $ ma nulla di fatto :(
gurutech
26-01-2008, 22:17
ciao!
se il programma non è concepito per andare in background (ad esempio gli script di shell non lo sono), faresti megli a mandarlo in background con "nohup"
[email protected]:~$ man nohup
NOHUP(1) User Commands NOHUP(1)
NAME
nohup - run a command immune to hangups, with output to a non-tty
SYNOPSIS
nohup COMMAND [ARG]...
nohup OPTION
DESCRIPTION
Run COMMAND, ignoring hangup signals.
[...]
esempio
nohup /home/test/mioscript.sh &
gurutech
26-01-2008, 22:19
ciao grillosoft,
ho provato a lanciare i processi con sh, ma in questo modo TUTTI i processi mi restituiscono un errore..
sh processo3.exe ----> processo3.exe: 1: Syntax error: "(" unexpected
poi ho provato a lanciare solo sh, e lanciare i comando da $ ma nulla di fatto :(
sh potrebbe essere linkato a qualcosa di diverso da bash (in ubuntu /bin/sh è un link simbolico a dash... no non al detersivo :D )
meglio allora fare
bash processo3.exe
maledizione... nulla da fare....
queste cose mi fanno uscir fuori di matto!!!
ma sai perchè??
perchè dopo aver perso ore e ore a preparare le mie applicazioni in c, mi ritrovo bloccato in questa maledetta cosa incredibile!!!
anche perchè se io lancio tutto da Makefile, tipo così
pippo:
./processo1.exe &
./processo2.exe &
...
...
./processo5.exe &
e da shell lancio make pippo funziona!!!
in realtà non funziona perchè in tal modo il processo 3 che appunto deve gestire il filedescriptor 0(cioè lo stdin) impazzisce, e ad ogni cilco mi entra nella parte di codice che gestisce l'input da tastiera e quindi mi da risultati non voluti, ma pero' a parte questo tutto va bene...
invece se lancio GLI STESSI comandi da shell... 1 volta mi va e 10 no per via del problema che ho riportato sopra...
ma vi sembra normale??
gurutech
27-01-2008, 11:17
[...]
perchè dopo aver perso ore e ore a preparare le mie applicazioni in c, mi ritrovo bloccato in questa maledetta cosa incredibile!!!
[...]in realtà non funziona perchè in tal modo il processo 3 che appunto deve gestire il filedescriptor 0(cioè lo stdin) impazzisce, e ad ogni cilco mi entra nella parte di codice che gestisce l'input da tastiera e quindi mi da risultati non voluti, [...]
puoi spiegare a grandi linee cosa hai bisogno di fare? magari postando qualche pezzo di codice.
può darsi che così troviamo una soluzione
#!/bin/bash
sleep 3
echo metti pippo
read pippo
echo $pippo
e poi
#!/bin/bash
./test.sh <<EOF &
ciao
EOF
funge cosi?
Comunque non e chiaro se tutta la catena di processi deve sospendersi per l'input, oppure l'input sara' sempre costante
E se lanci mandando tutti gli output in /dev/null?
comando 2>&1>/dev/null &
come ti hanno gia' chiesto, i programmi sono fatti per andare in bg?
gurutech
27-01-2008, 12:46
Prescrizioni per un programma daemon (http://www.lilik.it/~mirko/gapil/gapilsu161.html#x390-20700010.1.5)
può essere utile?
Grazie a tutti per i vostri aiuti,
li ho provati ma non hanno portato a nessun miglioramento
(devo ancora leggere l'ultimo link, lo faro' appena finito di scrivere questo post)
Provo a rispondere alle vostre domande:
come detto precedentemente, uso 5 processi.
tali processi, riassumendo, non fanno altro che passarsi dati su canali TCP/IP per mezzo dei socket.
Il 3° processo, oltre a far transitare i dati dal processo 2 al 4, gestisce anche lo stdin, al fine di poter simulare alcune casisteche nel caso vengano premuti dei tasti...
quindi mi sentirei di rispondere SI, i processi possono andare in background.
per farvi capire ancor meglio vi posto un po' di codice, cercherò di inserirne il minimo possibile, in modo da evitare di farvi perdere troppo tempo...
CODICE PROCESSO 2: DOPO ESSER STATO CONTATTATO DA PROCESSO 1 SI COLLEGA A PROCESSO 3
ris= TCP_setup_connection(&socketfd[j], string_remote_ip_address[j], remote_port_number[j], 10000000, 10000000,1 );
if (!ris) {
printf ("impossibile connettersi al server %s %d\nTERMINO!!\n", string_remote_ip_address[j], remote_port_number[j] );
fflush(stdout);
return(0);
} else {
printf ("Collegamento effettuato");
}
questo funziona e ricevo sempre la mia frase "Collegamento effettuato"
CODICE PROCESSO 3: DOPO ESSER STATO CONTATTATO DA PROCESSO 2 SI COLLEGA A PROCESSO 4 ( o meglio dovrebbe!!!) lo fa solamente ognitanto
rdset=all;
do {
ris=select(maxfd+1,&rdset,NULL,NULL,NULL);
} while( (ris<0) && (errno==EINTR) );
if(ris<0) {
perror("select failed: ");
exit(1);
}
else
{
for(i=0;i<numconndausare;i++)
{
if( (usalistenfd[i]) && (FD_ISSET(listenfd[i],&rdset )) )
{
/* accetto connessione e creo il thread */
OMISSIS
qui c'e' il codice che gestisce i canali in entrata uscita.
}
}
if( FD_ISSET(0,&rdset) )
{
char str[100];
fgets(str,100,stdin);
pthread_mutex_lock( &mutex_blocca );
BloccaConnessione=1; <------------
pthread_mutex_unlock( &mutex_blocca );
}
}
}
questa guardia if( FD_ISSET(0,&rdset) )
è quella che mi gestisce l'input da tastiera...
dovrebbe funzionare solo quando premo un tasto una volta che tutti e 5 processi sono partiti....
ma se per caso dopo aver lanciato ./processo3 & non mi viene data immediatamente la shell, lui cattura i tasti che premo per lanciare gli altri processi e io non vado + avanti....
Poi casomai il problema sta altrove, ma in tal caso non mi spiegherei come mai a volte va e a volte no....
per tagliare la testa al toro, ho inserito una frase di debug sotto la linea evidenziata dalla freccia <------
stampavo PIPPO, bene ogni volta che stampava PIPPO il programma non andava, altrimenti funzionava benissimo, o se prferite ogni volta che la pressione di un tasto attivava if( FD_ISSET(0,&rdset) ) il programma non funzionava.
ma per curiosità, voi, che immagino usiate spessissimo linux, e non solo per studio, quando lanciate un programma in background, cosa accade?
dentro quale delle 2 casistiche ricadete?
grazie ancora...
vado a leggere la guida dell'ultimo link, e nel caso aggiorno la situazione.
Ciao ciao
ma al posto di usare la pressione di un tasto per bloccare la procedura.. non puoi usare qalcosa di diverso?
tipo un file.. che se esiste blocca la procedura
mi sembra un po' un controsenso usar la pressioen di un tasto epr bloccare l'esecuzione di qualcosa che poi fai girare in background
sembra l'esame di sistemi 2 :D
poi perche vuoi farli andare in bg sulla stessa shell? se comunicano cosi potrebbero girare in 5 shell separate, tanto comunicano tramite socket, ed inoltre la situazione sarebbe piu' realisica visto che devi simulare 4/5 macchine, non una con 4 processi(senno non utilizzare socket ma pipe)
un processo in bg e solo un processo su cui la shell da un fork invece di un exec, condivide stderr e stdout con la shell, lo stdin e' gestito da un singolo processo alla volte (portandolo in fg o in bg, comandi shell tipo bg 1(nome job))
se ho capito bene, sulle 4 shell aperte un'ordine giusto sarebbe, processo 2, processo 3, processo 4 processo 1 (che da come ho capito e' quello che innesca il tutto)
siete troppo veloci a rspondere non vi sto dietro :)
[Per dupa]
se devo essere sincero, io sarei molto felice di poter attuare il tuo consiglio,
purtroppo pero' processo3 non posso toccarlo, così mi è stato dato e così me lo devotenere, pero' in questi giorni approfondendo un po' queste cose sulla rete, mi è parso di capire che un processo iterativo com'e' processo3 non dovrebbe girare in BG, ma se non lo faccio girare in BG non vedo come potrei finire di lanciare processo4 e processo5....
[Per Mason]
adesso provo immediatamente a lanciarlo da + shell... lo facevo dalla stassa perchè pensavo fosse una cosa intelligente ... :)
al fine di farli funzionare non ho un ordine prefissato da seguire... l'importante e che processo5 sia l'ultimo ad essere avviato.
E' lui che mette in modo, a cascata, tutti gli altri... ok forse avrei duvuto chiamarli in un altro modo... comunque p5 manda i dati a p4, il quale li manda a p3 e così via fino a p1....
si... era decisamente meglio numerarli al contrario... comunque semanticamente parlando non cambi nulla...
Scusa, non avevo visto che avevi risposto, igonra pure e segui quello di piu shell, e piu' naturale :)
forse non ci siamo inesi, non devi modificarlo quel processo, basta che apri 4 shell e su ognuna lanci un processo singolo
tutto dovrebbe funzionare
quello che vuoi tu, cioe che processo3 mantenga il canale stdin deve essere lanciato per ultimo senza &, ma questo e' contro il requisto, se ho ben capito, che il processo 1 sia quello che fa partire la catena di attivazione, quindi deve partire per ultimo quando tutto e su'.
pr1->pr2->pr3->pr4
/\
|
stdin
giusto?
Santo cielo...
avevi ragione...
ma non ci credo...
cioè se quel maledetto processo3 lo lancio in foreground da una seconda shell non ho problemi di sorta.... lui sta li' bello e buono finche nella prima shell non ho finito di lanciare tutti i miei processi....
l'unico neo è che l'output di p3 e quello di p1,p2,p4,p5 sono distinti... ovviamente... ma non penso sia un problema importante..
ma prima di cantar vittoria corro immediatamente a fare altri test...
comunqua vada grazie!!
ho imparato qualcosa di utile :)
mi pare di capire che la situazione sia:
--background--
proc1 parte, apre server1
proc2 parte, si collega a server1, apre server2
proc3 parte, si collega a server2, apre server3 (e gestisce comandi da stdin)
proc4 parte, si collega a server3, apre server4
proc5 parte, si collega a server4
--/background--
Io farei:
--background--
proc1 parte, apre server1
proc2 parte, si collega a server1, apre server2
proc4 parte, (ciclo di tentativi di connessione a server3), apre server4
proc5 parte, (ciclo di tentativi di connessione a server4)
--/background--
--foreground--
proc3 parte, si collega a server2, apre server3 (e gestisce comandi da stdin)
--/foreground--
Esatto dupa.. anch'io idealmente avrei voluto seguire quel modello, pero' non potevo lanciare per ultimo in FG p3, perchè appena partito p5 si collegava a p4 e se p4 non trovava dei socket in ascolto sull'indirizzo TCP/IP di p3 chiudeva baracca e burattini, e a quel punto anche p5 vistosi chiudere in faccia letteralemnte la porta smetteva di generare ed inviare messaggi...
aprendo p3 in un'altra shell invece risolvo il problema alla radice... perche' non puo' intercettare le pressioni dei miei tasti nella shell n.1 ma al contempo rimane raggiungibile via TCP perchè risiedono sulla stassa macchina...
sono così felice che potrei anche smettere di lavorarci per oggi :)
se non hai il requisito che processo 1 sia l'utlimo a partire, puoi anche lanciarli da singola shell
#!/bin/sh
pr1&
pr2&
pr4&
pr5&
pr3
edit:
letto ora che hai un vincolo di sequenza, ma chiarimo questo punto:
ma al contempo rimane raggiungibile via TCP perchè risiedono sulla stassa macchina..
potrei anche farlo girare sulla mia macchina il processo 3 che tutto deve funzionare, anzi, se i processi non sono residenti sulla stessa macchina usi i socket, altrimenti useresti le pipe.
cmq chiarimenti a parte, son contento hai risolto, son 5 euro :D
probabilemnte mi sono spiegato male sopra, ma ribadisco che ho l'esigenza di far partire per ultimo Processo5...
quindi la tua idea di usare shell differenti è una soluzione fantastica. :)
edito anch'io per risponderti
potrei anche farlo girare sulla mia macchina il processo 3 che tutto deve funzionare, anzi, se i processi non sono residenti sulla stessa macchina usi i socket, altrimenti useresti le pipe.
cmq chiarimenti a parte, son contento hai risolto, son 5 euro
esatto.. solo che come IP uso localhost :)
amo le pipe... ma l'idea del progetto è vedere se uno sa usare i socket...
peccato (o fortuna) che serva anche conoscere unix meglio di quanto lo conosca io... :) :)
per i 5 €... visto che non lavoro ti accontenti di un sacco di riconoscenza???? :)
gurutech
27-01-2008, 16:03
suggerimento per aspettare a lanciare processo5 sino a che processo3 non è partito in foreground
#!/bin/bash
ISACTIVE=""
echo -n "Waiting for an open xterm ."
while ( [ -z "$ISACTIVE" ] ); do {
echo -n "."
sleep 1
ISACTIVE="$(ps -C xterm -o comm h)"
}
done
echo " Done!"
se scrivo una cosa così, mi sgamano subito :)
no scherzi a parte, grazie gurutech, ma usando il trucco delle 2 shell risolvo bene il problema....
rimane il fatto che premuto un tasto, il sistema decide arbitrariamente di porre processo3 in stato 'suspended' e mi obblica a rimetterlo in foreground...
ma almeno ho superato il primo scoglio...
tralatro leggo su wikipedia, alla voce "Processo (informatica)"
bloccato (suspended): il thread ha eseguito una chiamata di sistema, ed è fermo in attesa del risultato
quindi immagino che in questo caso sia sufficiente guardare bene il codice per scoprire il problema..
altrimenti torno a rompervi le scatole :)
penso che con la wait sia meglio
che lo il polling tramite sleep e ps
ora che e' piu chiaro il problema, puoi lanciarli tutti in &
poi dai il comando jobs
vedi quale ti interessa portare in primo piano e dare fg numero
esemplifico:
mazzonma@mazzonma ~
$ ls test*sh
test1.sh test2.sh test3.sh
mazzonma@mazzonma ~
$ cat test1.sh
#!/bin/bash
sleep $[$RANDOM%10]
echo sono test1 metti pippo
read pippo
echo sono test1 $pippo
mazzonma@mazzonma ~
$ ./test1.sh &
[1] 3088
mazzonma@mazzonma ~
$ ./test2.sh &
[2] 2148
mazzonma@mazzonma ~
$ ./test3.sh &
[3] 2556
mazzonma@mazzonma ~
$ sono test3 metti pippo
sono test2 metti pippo
sono test1 metti pippo
[1]+ Stopped ./test1.sh
[2]- Stopped ./test2.sh
[3] Stopped ./test3.sh
mazzonma@mazzonma ~
$ jobs
[1]+ Stopped ./test1.sh
[2]- Stopped ./test2.sh
[3] Stopped ./test3.sh
mazzonma@mazzonma ~
$ fg 2
./test2.sh
ciaoooooo
sono test2 ciaoooooo
mazzonma@mazzonma ~
$ jobs
[1]+ Stopped ./test1.sh
[3] Stopped ./test3.sh
mazzonma@mazzonma ~
$ fg 1
./test1.sh
potrei continuare a tenere l'input su questo processo
sono test1 potrei continuare a tenere l'input su questo processo
mazzonma@mazzonma ~
$ fg
./test3.sh
peccato che i miei terminano dopo 1 lettura
sono test3 peccato che i miei terminano dopo 1 lettura
mazzonma@mazzonma ~
$ jobs
mazzonma@mazzonma ~
$
quindi li lanci come prima, quando ti si stoppa, controlli che job e' e gli fai riaquisire il conrollo dello stdin. Cosi forse otterresti tutti i log ordinati cronologicamente su un unica shell, a meno di informazioni sistemistiche
PS il suspend penso sia dovuto al fatto che lanci il pr3 con il &, toglilo e non avrai bisogno del fg
pps2 anzi, potresti metterlo al ultima riga del tuo script
potresti provare
indicaivo dopo pr3&
pr3&
pr4&
pr5&
...
alla fine
jobs|grep pr3|cut -c2
ma esemplifichiamo, voglio riesumare automaticamennte solo il test2 dei 3 precedenti:
$ cat lancer.sh
#!/bin/bash
./test1.sh &
./test2.sh &
./test3.sh &
echo risveglio automaticamente il test2
fg `jobs|grep test2|cut -c2`
mazzonma@mazzonma ~
$ #attenzione al . invece che ./
mazzonma@mazzonma ~
$ . lancer.sh
risveglio automaticamente il test2
sono test3 metti pippo
./test2.sh
sono test2 metti pippo
sono test1 metti pippo
ok gia questa riga e un comando, o almeno qualcosa scritto sull sdin di 2
sono test2 ok gia questa riga e un comando, o almeno qualcosa scritto sull sdin di 2
[1]+ Stopped ./test1.sh
[3] Stopped ./test3.sh
mazzonma@mazzonma ~
$ jobs
[1]+ Stopped ./test1.sh
[3] Stopped ./test3.sh
mazzonma@mazzonma ~
$
tu non avresti nulla in attesa visto che gl'altri processi proseguirebbero, mentre il processo da te interessato sarebbe risvegliao in automatico
anche questa volta avevi perfettamente ragione....
lanciando il processo in FG non il sistema me lo sospende...
grande :)
ho avuto un'ottima idea achiedere aiuto su questo forum :)
vBulletin® v3.6.4, Copyright ©2000-2026, Jelsoft Enterprises Ltd.