PDA

Visualizza la versione completa : [C & Unix] scrittura concorrente e strano file di output


}gu|do[z]{®©
14-12-2004, 11:39
Ho un programmino per l'Uni che deve tra le altre cose generare dei figli e far scrivere ad ognuno di questi un numero arbitrario di stringhe (minimo una) su un file di output.... il tutto usando solo le system calls di unix per l'I/O su file.

Il programma nella sua logica mi funziona perchè la stampa su stdout (per debug) è quello che mi aspetto... ma nel file di output mi trovo solo la prima stringa presente invece a video.. la cosa curiosa è che l'anteprima di KDE mi dice "1 riga, due parole, 400 e rotti caratteri".. mentre ad occhio i caratteri sono una trentina.... e se apro il file con vim trovo tutto quel che mi aspetto solo che le righe successive alla prima iniziano con una @....

Il problema, a parte questa cosa strana della @, è che non ho la certezza di quel che sto facendo.. ovvero non so se è necessario gestire in qualche modo migliore la concorrenza (e magari ora sembra funzionare perchè l'input è ristretto).

un sunto del mio codice:



main()
{
//bla bla bla

/*
Se le maschere sono giuste dovrebbe creare un file o
svuotarlo se esiste, con modalità di scrittura e
aggiornamento.
E' giusto? o ci va solo l'append senza il wronly? o che
altro?

f_out per comodità per ora è globale
*/
if((f_out = open("output",O_WRONLY|O_CREAT|O_TRUNC|O_APPEND, S_IRWXU)) < 0 ) //creo file di outupt
{
perror("Impossibile creare il file di output:");
exit(3);
}

//bla bla bla


/* genero un numero di figli variabile (la logica è già
testata e funziona).. ogni figlio invocherà un numero
variabile di volte la funzione che poi deve scrivere
l'output (una funzione che fa una lista dell'albero di una
directory)
*/
for(i=1,t=1; i<=num_proc; i++,t=t+per_proc)
{
switch(pid = fork())
{
case -1: //errore della fork
perror("Errore nella generazione dei figli: ");
exit(6);

case 0: //sezione del figlio
if(i==num_proc) per_proc = ultimo;

for(j=t;j<t+per_proc;j++)
{
get_dir(j,root_path);//seleziona la dir da analizzare
scan_dir(root_path);//analizza la dir
}
exit(0);

default:
continue;
}//fine switch
}//fine for
}//fine main


//la funzione che è chiamata da ogni figlio e che scrive in output
void scan_dir(char* root_path)
{
//bla bla bla


while((dir_entry = readdir(d_root)) != NULL)//per ogni elemento nella directory principale
{
//scarto i file speciali . e ..
//apro il file correntemente analizzato
//memorizzo il risultato di fstat su statbuf


//se la entry è un file effettuo il controllo sulla data
if(S_ISREG(statbuf.st_mode))
{
if(is_older(statbuf.st_mtime)>0) //stampa
{
sprintf(buff,"%s\n",path);
printf("%s",buff); //stampa su stdout solo per debug
if(write(f_out,buff,strlen(buff)+1)<0)
{
perror("Errore nella scrittura sul file di output.");
exit(5);
}
}
}
//Se la entry è una directory la esploro con una chiamata ricorsiva
else if(S_ISDIR(statbuf.st_mode)) scan_dir(path);

}//fine while
closedir(d_root);
}


se qualcuno ha la pazienza di darmi qualche dritta (o conferma) lo propongo per la beatificazione... ho un po' di urgenza perchè è solo una parte di una cosa più grossa e ho un collega di lavoro che mi ha bidonato e lasciato fare tutto solo.. :cry: [giusto per impietosirvi :D]

TNX
:ciauz:

}gu|do[z]{®©
14-12-2004, 13:31
ok.. la fesseria della chiocciola era dovuta ad un copia/incolla da del codice del mio collega.. -.-

cambiando
if(write(f_out,buff,strlen(buff)+1)<0)

con
if(write(f_out,buff,strlen(buff))<0)

non presenta più il problema...

mi rimane il dubio sulla concorrenza... i processi dovrebbero andare in parallelo.... quindi come mai non mi crea problemi di concorrenza?
Tra l'altro secondo le specifiche del progetto l'aoutput dev'essere "ordinato".. .cioè tutti i path analizzati da un processo devono essere raggruppati... con le mie prove viene già così senza che io debba far niente.. ma sempre il dubbio sulla concorrenza non mi lascia tranquillo (oltreytutto se il prof lo richiede esplicitamente dovrebbe essere qualcosa di non banale :\)

chi mi illumina?

kentaromiura
14-12-2004, 13:35
:dottò:
i processi generati con il fork non vanno di pari passo..
se e' questo che vuoi sapere..
cioe' l'esecuzione di un figlio prima dell' altro e' del tutto casuale.. :D

}gu|do[z]{®©
14-12-2004, 13:58
Originariamente inviato da kentaromiura
:dottò:
i processi generati con il fork non vanno di pari passo..
se e' questo che vuoi sapere..
cioe' l'esecuzione di un figlio prima dell' altro e' del tutto casuale.. :D

hum.. aspè...



La visita dell'albero delle directory deve essere effettuata in parallelo da un massimo di N processi distinti

[...]

Il file di output dovrebbe riportare l'output in modo ordinato includendo cioè, nella stessa porzione di file, tutti i file appartenenti ad un medesimo sottoalbero.


Che vanno in parallelo lo dice lui :stordita:

e quest'ultima specifica sull'output ordinato è quella che mi fa venire il dubbio che ci possa essere qualche condizione "strana" di concorrenza...
E' questo che non mi spiego.. lui parla di parallelismo ma se ci fosse il parallelismo dovrei garantire la mutua esclusione in scrittura e a quel punto avere l'output "ordinato" sarebbe un bordello...

:bhò:

}gu|do[z]{®©
15-12-2004, 11:56
up

per fungere funge ma mi fa strano che sia così semplice, in particolare viste le specifiche del prof :fagiano:

Loading