C Program is stuck, doesnt enter main()

420 Views Asked by At

I am trying to run a program where one thread takes data from standart input and than and the other gives it on a standart output, nothing too complicated, but when I run my program with /.filename < test.in > test.out it doesnt do anything. When I compliled it by using gcc -pthread filename.c -o filename -W -Wall, no errors or warnings seems to accour. Can someone explain? Also in file test.out nothing is displayed and in test.in is a simple sentence. This is the program

#define V  300

pthread_cond_t cond;
pthread_mutex_t mutex;
char a[300];
int p = 0;
int w = 0;


void *thread1() {

    while(1){
        pthread_mutex_lock(&mutex);
        printf("thread1");
        while(p >0){
            pthread_cond_wait(&cond, &mutex);
        }

        p = fread(a, sizeof(char), V ,stdin);

        if(p == 0){
            pthread_exit(NULL);
        }
        if(p <= V){ 
            pthread_cond_signal(&cond);
        }
        pthread_mutex_unlock(&mutex);
    }

}

void *thread2() {
    while(1){
        pthread_mutex_lock(&mutex);
        printf("thread2");

        while(w >0){
            pthread_cond_wait(&cond, &mutex);
        }

        w = fwrite(a, sizeof(char),p, stdout);

        if(w == 0){
            pthread_exit(NULL);
        }
        if(w <= V ){ 
            pthread_cond_signal(&cond);
        }
        pthread_mutex_unlock(&mutex);
    }
}

int main (void) {
    printf("main/n");
    fflush(stdout);
    pthread_t t1, t2; 

    pthread_mutex_init(&mutex, NULL);
    pthread_cond_init (&cond, NULL);

    pthread_create(&t1, NULL, vlakno1,  NULL);
    pthread_create(&t2, NULL, vlakno2,  NULL);


    pthread_join(t1, NULL);
    pthread_join(t2, NULL);

    pthread_mutex_destroy(&mutex);
    pthread_cond_destroy(&cond);
    return 0;
}
2

There are 2 best solutions below

4
bruno On BEST ANSWER

You have the obvious typo in your printf("main/n"); rather than printf("main\n"); (or just puts("main");) but this is a detail and not thre reason why your program will never finish

in vlakno1 you create a deadlock doing :

    if(poc_precitanych == 0){
        pthread_exit(NULL);
    }

because you do not unlock the mutext, must be

    if(poc_precitanych == 0){
        pthread_mutex_unlock(&mutex);
        pthread_exit(NULL);
    }

you have the same problem in vlakno2 :

    if(pocet_pisanych == 0){
        pthread_exit(NULL);
    }

must be

    if(pocet_pisanych == 0){
        pthread_mutex_unlock(&mutex);
        pthread_exit(NULL);
    }

The following is also strange :

    pocet_pisanych = fwrite(a, sizeof(char),poc_precitanych, stdout);

    if(pocet_pisanych == 0){
        pthread_exit(NULL);
    }

even it is not impossible, it is difficult to have a write on stdou without success. So the alone chance for you to go out that loop is to have poc_precitanych valuing 0

Additional remark, you #define V 300 but you do char a[300]; while you use V elsewhere. Better to do char a[V]; or to use sizeof(a) elsewhere without defining V


Examples of execution after the changes :

/tmp % ./a.out < /dev/null
main
vlakno 1vlakno 2

there is nothing to read so poc_precitanych values 0 and the two thread finishes, but

/tmp % echo "1 2 3" | ./a.out
main
vlakno 1vlakno 1vlakno 21 2 3
^C
1
chqrlie On

You do not see anything on the terminal because of the typo in printf("main/n");

printf's output is not flushed to stdout and the threads created consume loop for ever, or at least for a long time.

You should add fflush(stdout); after the printf statement to verify this.

Then you can try printf("main\n"); without the fflush() to verify that stdout is line buffered, ie: output is flushed to the terminal when a newline is output.

If you redirect output to a file, stdout is usually fully buffered, hence you should add an explicit fflush(stdout); after each output operation so you can see the output in the output file on the fly or after killing the program.

Note that the code would be easier to read for most users here if you use English words for the identifiers, types, comments and messages.