I tried to make a file copier using threads and somehow, the programm locks when entering the functions. I searched a lot and I tried many things, but I simply can't find the solution. I would be glad if somebody could help me!
//gcc -o threadcopyfile threadcopyfile.c -lpthread -lrt
#include <stdio.h>
#include <pthread.h>
#include <unistd.h>
#include <string.h>
#include <stdlib.h>
pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER; //init mutex
pthread_cond_t condRead = PTHREAD_COND_INITIALIZER; //init cond. variables
pthread_cond_t condWrite = PTHREAD_COND_INITIALIZER; //init cond. variables
int n, x = 1, i = 0, j, condition = 0;
char c;
pthread_t pRead;
pthread_t pWrite;
char ringpuffer[10000];
void *functionRead(void *argv){
char **args = (char **) argv; //Give args the arguments from argv
FILE* fp;
if ((fp=fopen(args[1], "r")) == NULL){ //Open the inputfile, check if failed
perror("fopen\n");
exit(EXIT_FAILURE);
}
n = atoi(args[3]);
printf("Entered functionRead\n");
do{
pthread_mutex_lock(&mutex); //Lock mutex
while(condition == 1){
pthread_cond_wait(&condRead, &mutex); //Wait for cond_signal
}
i = 0;
for(i = 0; i<=n; i++){ //Put chars into the ringbuffer
c = fgetc(fp);
ringpuffer[i] = c;
i++;
}
x++;
printf("Hit!");
condition = 1;
pthread_mutex_unlock(&mutex); //Unlock mutex
pthread_cond_signal(&condWrite); //Send signal to CondWrite
}while ((c=fgetc(fp)) != EOF);
if ((fclose(fp)) == EOF){ //Close the file
perror("fclose\n");
exit(EXIT_FAILURE);
}
return 0;
}
void *functionWrite(void *argv){
char **args = (char **) argv; //Give args the arguments from argv
FILE* fp;
if ((fp=fopen(args[2], "w")) == NULL){ //Open the outputfile, check if allowed
perror("fopen\n");
exit(EXIT_FAILURE);
}
n = atoi(args[3]);
printf("Entered functionWrite\n");
for (j = 0; j < x; j++){
pthread_mutex_lock(&mutex); //Lock mutex
while(condition == 0){
pthread_cond_wait(&condWrite, &mutex); //Wait for singel from condRead
}
fwrite(ringpuffer, 1, n, fp); //Write to file
printf("Hit too!");
condition = 0;
pthread_mutex_unlock(&mutex); //Unlock
pthread_cond_signal(&condRead); //Send signal again to condRead
}
if ((fclose(fp)) == EOF){
perror("fclose\n");
exit(EXIT_FAILURE);
}
return EXIT_SUCCESS;
}
int main(int argc, char **argv)
{
if (argc != 4){
printf("Only 3 parameters allowed!\n");
exit(EXIT_FAILURE);
}
printf("File to Copy: %s\nTarget: %s\nHow many chars: %s\n", argv[1], argv[2], argv[3]);
pthread_create(&pWrite, NULL, &functionWrite, ((void *)argv)); //Create thread, threadid in pWrite, execute functionWrite, and give argv as arguments
pthread_create(&pRead, NULL, &functionRead, ((void *)argv)); //Create thread, threadid in pRead, execute functionRead and give argv as arguments
printf("Threads created, file copy in progress\n");
pthread_cond_signal(&condRead); //Unblocks the thread
pthread_join(pRead, NULL);
pthread_join(pWrite, NULL);
printf("done.\n");
return 0;
}
You can't use a single mutex with two condition variables like that. If a thread calls pthread_cond_signal() and relocks the mutex before the second thread wakes up, the second thread will never be able to return from pthread_cond_wait() since it can't lock the mutex.
You also don't seem to be setting condition = 1, as both your functionRead() and functionWrite() have condition = 0 in them.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With