c - Applying fork() and pipe() (or fifo()) on counting words code -



c - Applying fork() and pipe() (or fifo()) on counting words code -

i've completed writing of counting words code finally. counts total number of words in files. (i.e. txt). now, want utilize multiple fork() access , read every file. studied in lastly week. besides, utilize global variable hold number of counted words. far know, if apply fork(), used global variables assigned 0. avoid it, tried utilize mmap() , similar functions okey. but, want utilize pipe() (fifo() if possible) communicate (hold values of numbers).

i utilize nftw() function go in folders , files. logic on below picture. how can utilize fork() , pipe() (fifo()) on code ? fork() complicated me because of inexperience. i'm new using of pipe() , fork(). according thought logic of code if can utilize fork() , pipe(), there fork() every file(i.e. txt) , access them using fork. if there folder , there files, 1 time again creates fork() 1 of created forks , access file. seek explain drawing below. give thanks you. want larn using of them.

int countineveryfolder(const char *dir)

is used because don't know how count files until next folder in nftw() function. number of files necessary because number of fork.

every folder should parent of files. files included folder.

code:

#include <stdio.h> #include <stdlib.h> #include <string.h> #include <unistd.h> #include <sys/types.h> #include <sys/stat.h> #include <sys/wait.h> #include <dirent.h> #include <errno.h> #include <ftw.h> #include <ctype.h> #include <sys/mman.h> #include <locale.h> #include <errno.h> #define max_path_len 2048 unsigned long total_words = 0ul; unsigned long total_dirs = 0ul; unsigned long total_files = 0ul; // proves counting number of file in folder int countineveryfolder(const char *dir) { struct stat stdirinfo; struct dirent * stfiles; dir * stdirin; char szfullname[max_path_len]; char szdirectory[max_path_len]; struct stat stfileinfo; int numoffile = 0; strncpy( szdirectory, dir, max_path_len - 1 ); if (lstat( szdirectory, &stdirinfo) < 0) { perror (szdirectory); homecoming 0; } if (!s_isdir(stdirinfo.st_mode)) homecoming 0; if ((stdirin = opendir( szdirectory)) == null) { perror( szdirectory ); homecoming 0; } while (( stfiles = readdir(stdirin)) != null) { if (!strcmp(stfiles->d_name, ".") || !strcmp(stfiles->d_name, "..")) continue; sprintf(szfullname, "%s/%s", szdirectory, stfiles -> d_name ); if (lstat(szfullname, &stfileinfo) < 0) perror ( szfullname ); /* file directory? */ if (s_isreg(stfileinfo.st_mode)) { printf( "filename: %s\n", szfullname ); numoffile++; } } // end while closedir(stdirin); homecoming numoffile; } // count words in files. unsigned long count_words_in_file(const char *const filename) { unsigned long count = 0ul; int errnum = 0; int c; file *in; in = fopen(filename, "rt"); if (in == null) { errnum = errno; fprintf(stderr, "%s: %s.\n", filename, strerror(errnum)); errno = errnum; homecoming 0ul; } /* skip leading whitespace. */ { c = getc(in); } while (isspace(c)); /* token loop. */ while (c != eof) { /* token word, if starts letter. */ if (isalpha(c)) count++; /* skip rest of token. */ while (!isspace(c) && c != eof) c = getc(in); /* skip trailing whitespace. */ while (isspace(c)) c = getc(in); } /* paranoid checking i/o errors. */ if (!feof(in) || ferror(in)) { fclose(in); fprintf(stderr, "warning: %s: %s.\n", filename, strerror(eio)); errnum = eio; } else if (fclose(in)) { fprintf(stderr, "warning: %s: %s.\n", filename, strerror(eio)); errnum = eio; } errno = errnum; homecoming count; } // recursively go in folders int nftw_callback(const char *filepath, const struct stat *sb, int typeflag, struct ftw *ftwbuf) { // directory if (typeflag == ftw_dp || typeflag == ftw_d) { total_dirs++; printf("%*s%s\n", ftwbuf->level * 4, "", filepath); //countineveryfolder(filepath); } // folder else if (typeflag == ftw_f) { total_files++; total_words += count_words_in_file(filepath); printf("%*s%s\n", ftwbuf->level * 4, "", filepath); } homecoming 0; } /* error message */ void err_sys(const char *msg) { perror(msg); fflush(stdout); exit(exit_failure); } int main(int argc, char *argv[]) { total_files = total_dirs = total_words = 0ul; if (nftw(argv[1], nftw_callback, 15, ftw_phys) == 0) { /* success! */ printf("%s: %lu files, %lu directories, %lu words total.\n", argv[1], total_files, total_dirs, total_words); } else { /* failed... */ err_sys("ntfw"); } putchar('\n'); //printf( "\ntotal words = %d\n\n", *wordcount); //printf( "\ntotal folders = %d\n\n", *foldercount); //printf( "\ntotal childs = %d\n\n", *childcount); //fork() homecoming 0; }

to start write programme 2 phases. single-process phase in file-paths queued (into linked-list or dequeue), , multi-process phase in worker processes receive work via pipe() , send counts main process via pipe(). main process utilize select() multiplex input children.

once understand how utilize select() pipe()s, work on having filepath discovery concurrent.

this design much easier implement in go, node.js, or greenlet python, learning how in c gives level of understanding underlying operations don't newer languages.

c linux pipe fork

Comments

Popular posts from this blog

java - How to set log4j.defaultInitOverride property to false in jboss server 6 -

c - GStreamer 1.0 1.4.5 RTSP Example Server sends 503 Service unavailable -

Using ajax with sonata admin list view pagination -