I
iwasinnihon
I am trying to teach myself more about synchronizing threads. I took
the following code from a book and have altered it to read one more
file (the program counts in the words in multiple files). The
original program from the book counted the words in 2 files. I want
to increase that to 3. However, when I add the 3rd thread it just
gets to a certain point and hangs. I think that the answer is to add
another condition variable, however, I can't quite grasp how I would
use this other variable. Can someone point me in the right direction?
#include <stdio.h>
#include <stdlib.h>
#include <pthread.h>
#include <ctype.h>
struct arg_set {
char *fname;
int count;
};
struct arg_set *mailbox;
pthread_mutex_t lock = PTHREAD_MUTEX_INITIALIZER;
pthread_cond_t flag = PTHREAD_COND_INITIALIZER;
int main( int ac, char *av[] )
{
pthread_t t1, t2, t3;
struct arg_set args1, args2, args3;
void *count_words(void *);
int reports_in = 0;
int total_words = 0;
if(ac != 4) {
printf("usage: %s file1 file2 file3\n", av[0]);
exit(1);
}
pthread_mutex_lock(&lock);
args1.fname = av[1];
args1.count = 0;
pthread_create(&t1, NULL, count_words, (void *) &args1);
args2.fname = av[2];
args2.count = 0;
pthread_create(&t2, NULL, count_words, (void *) &args2);
args3.fname = av[3];
args3.count = 0;
pthread_create(&t3, NULL, count_words, (void *) &args3);
while(reports_in < 3) {
printf("MAIN: waiting for flag to go up\n");
pthread_cond_wait(&flag, &lock);
printf("Main: Wow! flag was raised, I have the lock\n");
printf("%7d: %s\n", mailbox->count, mailbox->fname);
total_words += mailbox->count;
if(mailbox == &args1)
pthread_join(t1, NULL);
if(mailbox == &args2)
pthread_join(t2, NULL);
if(mailbox == &args3)
pthread_join(t3, NULL);
mailbox = NULL;
pthread_cond_signal(&flag);
reports_in++;
}
printf("%7d: total words\n", total_words);
}
void * count_words(void *a)
{
struct arg_set *args = a;
FILE *fp;
int c, prevc = '\0';
if((fp = fopen(args->fname, "r")) != NULL) {
while((c = getc(fp)) != EOF) {
if(!isalnum(c) && isalnum(prevc))
args->count++;
prevc = c;
}
fclose(fp);
}
else
perror(args->fname);
printf("COUNT: waiting to get lock\n");
pthread_mutex_lock(&lock);
printf("COUNT: have lock, storing data\n");
if(mailbox != NULL)
pthread_cond_wait(&flag, &lock);
mailbox = args;
printf("COUNT: raising flag\n");
pthread_cond_signal(&flag);
printf("COUNT: unlocking box\n");
pthread_mutex_unlock(&lock);
return NULL;
}
the following code from a book and have altered it to read one more
file (the program counts in the words in multiple files). The
original program from the book counted the words in 2 files. I want
to increase that to 3. However, when I add the 3rd thread it just
gets to a certain point and hangs. I think that the answer is to add
another condition variable, however, I can't quite grasp how I would
use this other variable. Can someone point me in the right direction?
#include <stdio.h>
#include <stdlib.h>
#include <pthread.h>
#include <ctype.h>
struct arg_set {
char *fname;
int count;
};
struct arg_set *mailbox;
pthread_mutex_t lock = PTHREAD_MUTEX_INITIALIZER;
pthread_cond_t flag = PTHREAD_COND_INITIALIZER;
int main( int ac, char *av[] )
{
pthread_t t1, t2, t3;
struct arg_set args1, args2, args3;
void *count_words(void *);
int reports_in = 0;
int total_words = 0;
if(ac != 4) {
printf("usage: %s file1 file2 file3\n", av[0]);
exit(1);
}
pthread_mutex_lock(&lock);
args1.fname = av[1];
args1.count = 0;
pthread_create(&t1, NULL, count_words, (void *) &args1);
args2.fname = av[2];
args2.count = 0;
pthread_create(&t2, NULL, count_words, (void *) &args2);
args3.fname = av[3];
args3.count = 0;
pthread_create(&t3, NULL, count_words, (void *) &args3);
while(reports_in < 3) {
printf("MAIN: waiting for flag to go up\n");
pthread_cond_wait(&flag, &lock);
printf("Main: Wow! flag was raised, I have the lock\n");
printf("%7d: %s\n", mailbox->count, mailbox->fname);
total_words += mailbox->count;
if(mailbox == &args1)
pthread_join(t1, NULL);
if(mailbox == &args2)
pthread_join(t2, NULL);
if(mailbox == &args3)
pthread_join(t3, NULL);
mailbox = NULL;
pthread_cond_signal(&flag);
reports_in++;
}
printf("%7d: total words\n", total_words);
}
void * count_words(void *a)
{
struct arg_set *args = a;
FILE *fp;
int c, prevc = '\0';
if((fp = fopen(args->fname, "r")) != NULL) {
while((c = getc(fp)) != EOF) {
if(!isalnum(c) && isalnum(prevc))
args->count++;
prevc = c;
}
fclose(fp);
}
else
perror(args->fname);
printf("COUNT: waiting to get lock\n");
pthread_mutex_lock(&lock);
printf("COUNT: have lock, storing data\n");
if(mailbox != NULL)
pthread_cond_wait(&flag, &lock);
mailbox = args;
printf("COUNT: raising flag\n");
pthread_cond_signal(&flag);
printf("COUNT: unlocking box\n");
pthread_mutex_unlock(&lock);
return NULL;
}