My intention is to transpose two files using multithreading. But the program below is giving me segmentation fault.
#include <stdio.h>
#include <stdlib.h>
#include <pthread.h>
#include <string.h>
void *a_to_temp( void *filea);
void copyFile( FILE *in, FILE *out );
void *temp_to_b( void *fileb);
void *b_to_a(void *ab);
struct files{
char a[80];
char b[80];
} ab;
pthread_mutex_t temptob = PTHREAD_MUTEX_INITIALIZER;
pthread_mutex_t btoa = PTHREAD_MUTEX_INITIALIZER;
main(int argc, char **argv)
{
fprintf(stderr, "in main");
pthread_t thread1, thread2, thread3;
strcpy( ab.a, argv[1]);
strcpy(ab.b, argv[2]);
int iret1, iret2, iret3;
pthread_mutex_lock( &temptob );
pthread_mutex_lock( &btoa );
iret1 = pthread_create( &thread1, NULL, a_to_temp, (void*) &argv[1]);
iret2 = pthread_create( &thread2, NULL, b_to_a, (void*) &ab);
iret3 = pthread_create( &thread3, NULL, temp_to_b, (void*) &argv[2]);
pthread_join( thread1, NULL);
pthread_join( thread2, NULL);
pthread_join( thread3, NULL);
exit(0);
}
void *a_to_temp( void *filea) {
FILE *a = fopen((char *)filea, "r");
FILE *f = fopen( "temp", "w");
copyFile( a , f);
fclose(f);
fclose( a);
pthread_mutex_unlock( &temptob );
}
void *temp_to_b( void *fileb) {
pthread_mutex_lock( &temptob );
FILE *b = fopen((char *)fileb, "r");
FILE *f = fopen( "temp", "r");
copyFile( f, b);
fclose(f);
pthread_mutex_unlock( &btoa );
}
void *b_to_a(void *ab) {
pthread_mutex_lock( &btoa );
FILE *a = fopen(((struct files *) ab)->a, "w"); //
FILE *b = fopen(((struct files *) ab)->b, "r");//
fprintf(stderr, "c files opened");
copyFile( b, a);
fclose(a);
fclose(b);
}
void copyFile( FILE *in, FILE *out) {
char ch;
while(!feof(in)) {
ch = getc(in);
if(!feof(in)) putc(ch, out);
}
}
I’ve tested the code until the end of the main function by printing values. I’m guessing that the error should be inside one of the functions.
You pass
&argv[1]to thea_to_temp()function, which is achar **, and then try to use it as if it was achar *. Ditto for&argv[2]and thetemp_to_b()function. This is not a recipe for happiness; a core dump is quite a plausible response.The simplest fix is to drop the
&in thepthread_create()calls. The alternative is to handle thechar **in the called functions.Note: this simply fixes the core dumps caused by accessing the wrong data. There may be algorithmic problems with the code too, ensuring that the correct synchronization occurs. And it is debatable whether there is any performance gain to using threads here. Indeed, there probably isn’t. But that is presumably tangential to the point of the exercise, which is to get threaded code working at all.
One item would be to ensure you error check every system call; at the moment, you are assuming everything will work. However, I think Jay is on the right track with ‘the thread that locks a mutex must unlock it too’. You probably want one or two conditions (
pthread_cond_init()et al) controlling access to the files instead of the mutexes.