00001 /* 00002 Thread example (background sorting; with mutexes) 00003 AUP2, Sec. 5.17 (not in book) 00004 00005 Copyright 2003 by Marc J. Rochkind. All rights reserved. 00006 May be copied only for purposes and under conditions described 00007 on the Web page www.basepath.com/aup/copyright.htm. 00008 00009 The Example Files are provided "as is," without any warranty; 00010 without even the implied warranty of merchantability or fitness 00011 for a particular purpose. The author and his publisher are not 00012 responsible for any damages, direct or incidental, resulting 00013 from the use or non-use of these Example Files. 00014 00015 The Example Files may contain defects, and some contain deliberate 00016 coding mistakes that were included for educational reasons. 00017 You are responsible for determining if and how the Example Files 00018 are to be used. 00019 00020 */ 00021 #include "defs.h" 00022 #include <pthread.h> 00023 00024 #define MAX_ENTRIES 100 00025 00026 struct dict { 00027 int d_nentries; 00028 char *d_entry[MAX_ENTRIES]; 00029 bool d_issorted; 00030 }; 00031 00032 static pthread_mutex_t mtx = PTHREAD_MUTEX_INITIALIZER; 00033 00034 static int compar(const void *x, const void *y) 00035 { 00036 return strcmp(*(char **)x, *(char **)y); 00037 } 00038 00039 static void *sorter(void *arg) 00040 { 00041 struct dict *d = arg; 00042 00043 while (true) { 00044 ec_rv( pthread_mutex_lock(&mtx) ) 00045 if (!d->d_issorted) { 00046 qsort(d->d_entry, d->d_nentries, sizeof(char *), compar); 00047 d->d_issorted = true; 00048 } 00049 ec_rv( pthread_mutex_unlock(&mtx) ) 00050 sleep(1); 00051 } 00052 00053 EC_CLEANUP_BGN 00054 exit(EXIT_FAILURE); 00055 EC_CLEANUP_END 00056 } 00057 00058 int main(void) 00059 { 00060 struct dict dictionary; 00061 pthread_t tid; 00062 char word[100]; 00063 int i; 00064 size_t wordlen; 00065 00066 dictionary.d_nentries = 0; 00067 dictionary.d_issorted = true; 00068 ec_rv( pthread_create(&tid, NULL, sorter, &dictionary) ) 00069 while (true) { 00070 printf("Word? "); 00071 if (fgets(word, sizeof(word), stdin) == NULL && ferror(stdin)) 00072 EC_FAIL 00073 if (feof(stdin)) 00074 break; 00075 if (word[0] == '-') { 00076 ec_rv( pthread_mutex_lock(&mtx) ) 00077 if (dictionary.d_issorted) 00078 for (i = 0; i < dictionary.d_nentries; i++) 00079 printf("\t%s\n", dictionary.d_entry[i]); 00080 else 00081 printf("Not sorted -- try again later\n"); 00082 ec_rv( pthread_mutex_unlock(&mtx) ) 00083 continue; 00084 } 00085 wordlen = strlen(word); 00086 if (word[wordlen - 1] == '\n') 00087 word[--wordlen] = '\0'; 00088 if (dictionary.d_nentries >= MAX_ENTRIES) { 00089 errno = E2BIG; 00090 EC_FAIL 00091 } 00092 ec_null( dictionary.d_entry[dictionary.d_nentries] = 00093 malloc(wordlen + 1) ) 00094 strcpy(dictionary.d_entry[dictionary.d_nentries], word); 00095 ec_rv( pthread_mutex_lock(&mtx) ) 00096 dictionary.d_nentries++; 00097 dictionary.d_issorted = false; 00098 ec_rv( pthread_mutex_unlock(&mtx) ) 00099 } 00100 printf("Done\n"); 00101 return EXIT_SUCCESS; 00102 00103 EC_CLEANUP_BGN 00104 return EXIT_FAILURE; 00105 EC_CLEANUP_END 00106 }