#include #include #include #include #include #include #define PARENT "parent" #define MAXNTH 20 char* str; char** files; int file_count; /* Number of files yet to search. */ int th_count; /* Number of threads currently in use. */ int th_count_max; /* Maximum number of threads to use. */ pthread_mutex_t file_lock; pthread_mutex_t print_lock; pthread_mutex_t count_lock; pthread_cond_t th_cond; static void* search(); extern char* getenv(); extern char* index(); main(int argc, char** argv) { int i, status; char* parallel; pthread_t thread; char thread_name[257]; if (argc < 3) { usage(argv[0]); exit(1); } str = argv[1]; file_count = argc - 2; files = &argv[2]; if ((parallel = getenv("PARALLEL")) == NULL) th_count_max = 1; else th_count_max = atoi(parallel); th_count_max = (th_count_max > MAXNTH)? MAXNTH : th_count_max; if (file_count < th_count_max) th_count_max = file_count; printf("th_count_max: %d\n", th_count_max); pthread_mutex_init(&file_lock, NULL); pthread_mutex_init(&print_lock, NULL); pthread_mutex_init(&count_lock, NULL); pthread_cond_init(&th_cond, NULL); th_count = 0; for (i = 1; (i < th_count_max) && (file_count > 0); i++) { sprintf(thread_name, "thread %d", i); status = pthread_create(&thread, NULL, (void*)search, (void*)thread_name); if (status != 0) { perror("pthread_create"); exit(0); } pthread_detach(thread); } if (file_count > 0) search(PARENT); pthread_mutex_lock(&count_lock); while (th_count > 0) pthread_cond_wait(&th_cond, &count_lock); pthread_mutex_unlock(&count_lock); exit(0); } static void* search(void* parent_flag) { char* cur_file; printf("search %s.\n", parent_flag); pthread_mutex_lock(&count_lock); th_count++; th_count_max--; pthread_mutex_unlock(&count_lock); pthread_mutex_lock(&file_lock); while (*files != NULL) { cur_file = *files++; file_count--; pthread_mutex_unlock(&file_lock); search_file(cur_file); pthread_mutex_lock(&file_lock); } pthread_mutex_unlock(&file_lock); pthread_mutex_lock(&count_lock); th_count--; pthread_mutex_unlock(&count_lock); if (parent_flag != (char*)PARENT) { pthread_cond_signal(&th_cond); pthread_exit(0); } } search_file(char* file) { FILE* fp; int match_found; char line[BUFSIZ]; char *p, *p1; char *s, *s1; if ((fp = fopen(file, "r")) == NULL) { perror(file); return 1; } while (fgets(line, BUFSIZ, fp) != NULL) { s = str; match_found = 0; p = line; while ((p = index(p, *s)) && !match_found) { if (strncmp(p, str, strlen(str)) == 0) match_found = 1; p++; } if (match_found) { pthread_mutex_lock(&print_lock); printf("%s: %s", file, line); pthread_mutex_unlock(&print_lock); } } fclose(fp); return 0; } usage(char* prog) { printf("Usage: %s ...\n", prog); }