#include #include #include #include #include #include #include #include #include #include #include #include #include /* ***esercizio B7 'ricerca in file con più processi' *** Il programma prende tre parametri: un nome di file, un numero intero > 0 (M), una stringa di caratteri S da cercare nel file All’interno di un file passato come argomento al programma, questo crea M processi Ciascun processo cerca nel pezzo di file assegnato la stringa S (se la trova, scrive a video l’offset della stringa nel file) Ciascun processo opera su un pezzo del file di dimensione pari a file_size/M + K (con K >=0 tale che se la stringa S è a cavallo di due pezzi contigui, S venga trovata) problema: come si potrebbero raccogliere i risultati di ciascun processo, per costruire un elenco completo dei risultati? in aggiunta: contare il numero totale di occorrenze nel file della stringa da cercare */ #define M 4 int main() { // usiamo il file https://github.com/marcotessarotto/exOpSys/blob/master/res/text01.txt char * filename = "text01.txt"; char * search_string = "est"; int search_string_len; int fd; char * map; struct stat st; pid_t pid; search_string_len = strlen(search_string); fd = open(filename, O_RDWR); if (fd == -1) { perror("open"); exit(1); } if (fstat(fd, &st) == -1) { perror("fstat"); exit(1); } // può anche essere un MAP_PRIVATE; a sola lettura map = mmap(NULL, st.st_size, PROT_WRITE | PROT_READ, MAP_SHARED, fd , 0); if (map == MAP_FAILED) { perror("mmap"); exit(1); } if (close(fd) == -1) { perror("close"); exit(1); } int file_piece_len = st.st_size / M; for (int i = 0; i < M; i++) { pid = fork(); if (pid == -1) { perror("fork"); exit(1); } // esempio: // search string: "ABC" // "---file piece-----" // ABC // nel caso "peggiore", la stringa da cercare ha il primo carattere // all'ultima posizione del pezzo di file corrente, per questo motivo andiamo a cercare // "un po' oltre" la fine del pezzo: strlen(search_string) - 1 if (pid == 0) { int start = file_piece_len * i; int end = file_piece_len * (i+1); if (end < st.st_size) end = end + search_string_len - 1; printf("[child] #%d start=%d end=%d\n", i, start, end); char * ptr = &map[start]; while (1) { ptr = strstr(ptr, search_string); if (ptr == NULL) break; if (ptr > map + end) break; ptr = ptr + search_string_len; printf("[child] #%d found string at position: %ld\n", i, ptr - map); } printf("[child] #%d bye\n", i); exit(0); } } while (wait(NULL) == -1) ; printf("[parent] bye\n"); return 0; } /* * caso M = 1 [child] #0 start=0 end=3766 [child] #0 found string at position: 284 [child] #0 found string at position: 648 [child] #0 found string at position: 871 [child] #0 found string at position: 1020 [child] #0 found string at position: 1030 [child] #0 found string at position: 1048 [child] #0 found string at position: 1464 [child] #0 found string at position: 1894 [child] #0 found string at position: 1906 [child] #0 found string at position: 1965 [child] #0 found string at position: 2138 [child] #0 found string at position: 2167 [child] #0 found string at position: 2710 [child] #0 found string at position: 2733 [child] #0 found string at position: 2909 [child] #0 found string at position: 2980 [child] #0 found string at position: 3023 [child] #0 found string at position: 3294 [child] #0 found string at position: 3302 [child] #0 found string at position: 3538 [child] #0 found string at position: 3608 [child] #0 bye [parent] bye */