Visualizzazione dei risultati da 1 a 3 su 3
  1. #1

    Analisi testuale di un file

    Salve, sto preparando l'esame di sistemi operativi e ho delle cose poco chiare riguardo la gestione dei file da parte del kernel di windows tramite system call. Stavo preparando del codice per analizzare un file: il programma legge una sequenza e la ricerca nel file, e conta in quante parole questa sequenza si trova. L'idea era di progettare un processo multithreading:un thread si mette ciclando alla richiesta di nuove sequenze, e lancia a sua volta un thread per la ricerca. Alla fine, dopo il carattere '.', restituisce il risultato. La mia domanda è questa:l'accesso concorrenziale al file è gestito direttamente dalla creazioni del thread?In poche parole, se effettuo l'apertura del file dal main e passo al thread solo la sequenza da ricercare, ogni volta che lancio una ReadFile nel thread ho un nuovo file pointer al file che punta quindi all'inizio del file? Sembrerebbe di no, vi chiedo questo, perchè effettivamente non so come uscirne: se inserisco 2 sequenze il programma entra in stallo (si blocca alla chiamata WaitForMultipleObjects)... Dovrei forse usare i semafori (cosa che abbiamo studiato da pochissimo e ancora devo capire bene)?E se si, come?
    Grazie per un'eventuale risposta

  2. #2
    Non so se ho ben capito...ma posso dire che (per quel che ne so):
    - i thread non fanno nulla sui file; sei tu che in un thread gestisci un file, quindi è compito tuo gestire la concorrenza; se due thread usano lo stesso handle di file in effetti stanno usando lo stesso file (con lo stesso file pointer) e quindi possono succedere i peggio casini; se invece tu apri un file in un thread e poi lo passi ad un'altro thread per la gestione non ci dovrebbero essere problemi (ma il primo thread non ci deve fare più nulla con l'handle);
    - ogni ReadFile che fai non crea un nuovo file pointer (che è unico per un file e rappresenta solo la posizione nel file) ma sposta il file pointer in avanti, quindi difficilmente torna all'inizio del file; per spostarlo all'inizio del file devi usare una SetFilePointer;
    - sinceramente non capisco l'uso della WaitForMultipleObjects; per quanto riguarda i semafori dipende da quello che vuoi fare, per quel che ne ho capito vorresti semplicemente sincronizzarti sulla fine di un thread e forse un event per ogni thread è meglio (CreateEvent).
    Io farei qualcosa del genere:
    - per prima cosa creo un thread di gestione (ThreadFunc A=TFA) e un evento (EVA);
    - sto in attesa (in qualche modo) di una sequenza e di un nome di file;
    - in TFA: attendo l'evento EVA;
    - quando ho una sequenza la metto su una coda e segnalo l'evento EVA;
    - in TFA: scarico la sequenza dalla coda, creo un thread (TFB) ed un evento (EVB);
    - in TFA: ritorno in attesa di EVA e di EVB (qua ci vuole la WaitForMultipleObjects);
    - in TFB: apro il file con CreateFile
    - in TFB: scorro il file con la ReadFile e cerco la sequenza se la trovo la metto in una coda
    associata a TFB;
    - in TFB: alla fine segnalo l'evento EVB e termino chiudendo il file;
    - in TFA: vedo quale thread è terminato e scodo la sua coda con i match della sequenza e ne faccio qualcosa (eventualmente li passo al processo principale in qualche modo);
    - in TFA: torno in attesa di EVA (ora EVB non c'è più).
    ho fatto l'esempio con un thread TFB ma è lo stesso con più thread; il thread TFA potrebbe essere evitato usando solo il processo principale e unendo l'attesa delle sequenze con l'attesa dei risultati (se però usi il thread TFA puoi riutilizzare il programma anche per altri scopi che richiedano la gestione di file con più thread); una nota: se apri il file in condivisione di lettura puoi processare lo stesso file da più thread (ognuno avrà il suo handle ed il suo file pointer).
    Un bel lavoretto direi....buona codifica

  3. #3
    Grazie mille per la risposta... Parte di ciò che hai detto ne ero già a conoscenza, in particolare di questo...
    una nota: se apri il file in condivisione di lettura puoi processare lo stesso file da più thread (ognuno avrà il suo handle ed il suo file pointer).
    E' quello che ho fatto, aprendo il file con FILE_SHARE_READ... Probabilmente il mio errore è quello di lavorare con un handle globale. In altre parole, al thread della ricerca non passo come parametro un handle, ma solo la sequenza da ricercare... Per la tua domanda del perchè usassi WaitForMultipleObjects, l'ho fatto per fare in modo che il thread della ricerca, una volta terminate le sequenze da inserire, attendesse l'uscita di tutti i thread prima di mostrare l'output. Copio il codice, abbi pietà ma è ancora in fase embrionale...

    #include <windows.h>
    #include <stdlib.h>
    #include <stdio.h>
    #include <string.h>
    #define LENGHT 20

    typedef struct {
    char* parola;
    int occorrenze;} risultato;

    risultato array[50];
    HANDLE rf;

    void cerca (risultato *ris) //Scarica la parola in un buffer
    { //e vede se è una sottostringa di una parola del file
    DWORD letti;
    int lettiprima=0;
    int leggere=LENGHT;
    char buffer[LENGHT];

    while(ReadFile(rf, buffer, leggere, &letti, NULL))
    {
    while(leggere>=1){
    lettiprima=lettiprima+letti;
    leggere=leggere-letti;
    ReadFile(rf, &buffer[lettiprima], leggere, &letti, NULL);
    }
    if(strstr(buffer,ris->parola)!=NULL)
    ris->occorrenze=ris->occorrenze+1;
    leggere=LENGHT;
    letti=0;
    lettiprima=0;
    }
    ExitThread(1);
    }

    void main ()
    {
    HANDLE collezione [50];
    int i=0, j;
    DWORD hid;
    char buff[LENGHT];
    rf=CreateFile("prova.txt",GENERIC_READ,FILE_SHARE_ READ,
    NULL,OPEN_EXISTING,FILE_ATTRIBUTE_NORMAL,NULL);
    if (rf==INVALID_HANDLE_VALUE)
    {printf ("Impossibile aprire il file!");
    ExitProcess(1);
    }
    printf("Inserisci sequenza da ricercare ");
    scanf("%s",&buff);
    while( strcmp(buff,".")!=0 )
    {array[i].parola=strdup(buff);
    array[i].occorrenze=0;
    collezione[i]=CreateThread(NULL, 0, (LPTHREAD_START_ROUTINE) cerca, &array[i],
    NORMAL_PRIORITY_CLASS, &hid);
    if (collezione[i]==NULL)
    {printf("Creazione thread fallita!");
    ExitProcess(1);
    }
    printf("\nInserisci sequenza da ricercare ");
    scanf("%s",&buff);
    i=i+1;
    }
    WaitForMultipleObjects(i-1, collezione, TRUE, INFINITE);
    CloseHandle(rf);
    for (j=0;j<i;j++)
    printf("\nLa sequenza %s occorre in %d parole",array[j].parola, array[j].occorrenze);
    }

Permessi di invio

  • Non puoi inserire discussioni
  • Non puoi inserire repliche
  • Non puoi inserire allegati
  • Non puoi modificare i tuoi messaggi
  •  
Powered by vBulletin® Version 4.2.1
Copyright © 2025 vBulletin Solutions, Inc. All rights reserved.