PDA

Visualizza versione completa : Semplice domanda: perché non funziona?


Efreet
11-05-2002, 12.20.18
Ciao a tutti,
ho fatto questo semplice programma in C per aprire un file, leggerlo e scriverlo su un altro file creato dal programma. Tutto ha funzionato bene; poi ho deciso di aggiungere un ciclo for per rendere tutto maiuscolo, e qui si rifiuta di compilare: perché? Mi ci sto rompendo la testa, mi dice sempre: parse error nella riga del for. Ma che diamine devo fare?!? Mi sembra corretto! Ecco il codice (è nell'allegato, a proposito come si fa il copia-incolla in Linux?).

Grazie a tutti, ciao!

Ibanez
11-05-2002, 14.01.06
Per l'errore + comune del mondo, i punti e virgola nel for:) .

for(i=0; i<nread; i++) .

Efreet
11-05-2002, 14.03.41
Mapporc... a furia di open(A,B,C) e e creat(A,B) me l'ero proprio scordato!

Grazie mille :D

Efreet

Ibanez
11-05-2002, 14.07.45
Figurati:)

pholcus
11-05-2002, 16.44.22
Dipende dall'editor..in kwrite e in generale in kde e' come windows..ctrl-c=copia , ctrl-v=incolla, ctrl-x=taglia.
Tu mi pare usi emacs vero? E' un po più macchinoso..in pratica devi settare un 'mark' nel punto in cui vuoi tagliare ( ctrl-@)poi con le frecce selezioni il testo, poi ctrl-w per tagliare e ctrl-y per incollare.

Per quanto riguarda il codice io aggiungerei un if all'inizio per controllare che effettivamente i parametri da linea di comando siano 2 cioè il file da cui leggere e il file su cui scrivere.

if (argc != 3){
printf("usage: <nome_programma> <file_in> <file_out>");
exit(0);
}

Poi dove ci son le perror():

if ((infile = open(argv[1], O_RDONLY)) == -1){
perror("failed opening source file");
exit(0);
}
if ((outfile = creat(argv[2], perm)) == -1){
perror("failed creating target file");
exit(0);
}

Cosi se per qualche motivo nn riuscisse a creare o ad aprire i file il programma esce subito..

Ciao

Efreet
12-05-2002, 12.40.28
Prima di tutto grazie per l'aiuto e i consigli che sono sempre ben accetti :D, secondariamente ho un altro problema da proporvi.

Sto tentando di imparare il controllo di processi e per questo ho creato un piccolo programma in cui il padre crea N figli e poi attende la loro chiusura. Una volta verificato che questo funzionava, ho tentato di fare in modo che il padre attendesse i figli in ordine di creazione, ossia il padre crea i processi 1, 2, 3, 4..., che altro non fanno che aspettare un secondo e uscire, mentre il padre attende la loro chiusura in ordine crescente.

Disgraziatamente neanche questo programma sembra funzionare correttamente: gcc lo compila, ma poi quando lo lancio mi viene una serie di scritte tutte uguali con -1 al posto del PID desiderato, per tutti i processi figli.

Che cosa ho sbagliato?
Grazie ancora, ciao!

Efreet

P.S.
1) Tento sempre di inserire il file .c ma non mi lascia, quindi metto ancora il .txt :)
2) Dimenticavo: sì, uso Emacs :D

Efreet
12-05-2002, 12.52.36
Per il copia-incolla, intendevo dire questo: come faccio a copiare il testo da un'applicazione qualsiasi e a incollarlo in un'altra? Mi pare che non ci si riesca, anche nell'editor avanzato faccio CTRL+C e poi mi sposto in Mozilla per incollare nelle risposte ma non succede niente :( e questo è un po' scomodo...

Comunque riporto il codice trascrivendolo a mano, per chi non ha voglia di aprire l'allegato:

#include <unistd.h>
#include <sys/wait.h>
#include <sys/types.h>

#define N 8

int main() {
int status, i;
pid_t pid, ppid;

ppid = getpid()+1;

/* Il padre crea N processi figli */
for ( i=0 ; i<N ; i++ )
if ((pid=fork())==0)
{
sleep(1);
exit(10+i);
}

/* Il padre attende i figli in ordine cronologico */
for ( ppid ; ppid<ppid+N ; ppid++ )
{
pid=waitpid(ppid, &status, 0);
if(WIFEXITED(status))
printf("Il figlio %d ha terminato correttamente con exit status %d\n", pid, WIFEXITED(status));
else
printf("Il figlio %d non ha terminato correttamente\n", pid);
}

exit(0);
}

pholcus
12-05-2002, 15.56.26
Cosi nn può funzionare..
Perchè non è detto che il numero del process id sia per forza ppid+n ; perchè potrebbe capitare che un altro processo venga creato diciamo tra due fork (per esempio figlio1=1234, processo_esterno=1235, figlio2=1236 ).

Poi dove c'è il ciclo for

/* Il padre crea N processi figli */
for ( i=0 ; i<N ; i++ )
if ((pid=fork())==0)
{
sleep(1);
exit(10+i);
}


io lo scriverei cosi..


for (i=0;i<Ni++){
if ( (pid=fork()) < 0)perror("fork ");

if (pid==0){
sleep;
exit(0);
}
}



Ora come ora per gestire i pid dei processi, direi di creare un array contenente i pid, cosi anche se non sono in ordine puoi fare la waitpid comunque..

Ciao

Ciao

Efreet
12-05-2002, 16.37.13
Ciao,
ho considerato i tuoi suggerimenti ma non saprei realizzarli in pratica. Il ciclo for è sicuramente migliore, appena posso lo sistemo. Sono riuscito a ottenere che i processi si chiudessero in ordine di PID (supponendo che non venissero creati processi tra l'uno e l'altro) con qualche smanettamento, ma purtroppo ora sono in Windows e non posso accedere al codice (mannaggia a Bill).

Comunque non mi è chiarissimo il funzionamento dei fork()... speriamo che nel compito ci metta delle cose facili (tipo crea un processo figlio che fa una printf e esce!).

La mia idea sarebbe, comunque, di fare in modo che per ogni figlio il padre possa ottenere il pid corrispondente e cacciarlo nell'array come dici tu; ma come faccio? Una volta che ho l'array li faccio finire nello stesso ordine, ma il problema per me è proprio creare l'array. Idee?

Grazie,
Efreet

pholcus
12-05-2002, 17.01.11
Si, nn è semplice da capire la fork.

In pratica la fork crea una copia del processo. Pero' la cosa che di solito nn e' molto chiara da capire che i valori ritornati sono due.
Cioè al processo figlio viene assegnato 0 ( ecco perchè c'è l' if pid ==0{ <entra_nel_figlio> } ) e al processo padre viene ritornato il pid del figlio.
Ti conviene imparare bene la fork perchè e' fondamentale, soprattutto per le applicazioni di rete.

Un consiglio: se ti incasini con gli if ( cosa che succede spesso se si chiamano diverse fork() ) ti conviene creare delle procedure che gestiscono il codice, e' piu' semplice.


processo padre
|
|
fork()-----------------------------processo figlio
| |
| |
procedura_padre() procedura_figlio()
| |
| |
wait() <-------------------------------exit
|
|
exit


Un esempio.

main(){

fork()

if(figlio){
P_figlio();
}
else{
P_padre();
}
}

P_figlio(){
/*codice del figlio da eseguire*/
}

P_padre(){
/*codice del padre da eseguire*/
}


Ciao

Efreet
12-05-2002, 21.22.33
Grazie per la spiegazione del fork(), forse ho capito come fare quell'array di cui parlavamo:


#define N 10

int main() {
pid_t pid;
int i;
int pids[N]; /* Raccoglie i PID dei processi creati */

for ( i=0 ; i<N ; i++) /* creo N figli */
{
if ((pid=fork())!=0)
pids[i] = pid; /* il padre raccoglie i vari pids */
if (pid==0)
{/* codice di ogni figlio, tipo wait(3) */}
}

if (pid!=0) for ( i=0 ; i<N ; i++)
printf("PID in ordine: %d\n", pids[i]);

}

Ti pare sensato? :D A proposito, pid_t in realtà è un int o che diamine di tipo è?

Ciao,
Efreet

pholcus
12-05-2002, 21.33.20
A vederlo cosi dovrebbe funzionare..

pid_t è in pratica è un int..la t sta per type, quindi sarebbe una variabile di tipo pid, che altro nn è che un int..le definizione dei vari tipi son nell'headr types.h

Ciao