-2
\$\begingroup\$

I'm trying to implement a c program using pthreads which prints "1 2 3 4 5" in an infinite loop. I have used conditional variables and mutex to synchronize the pthreads. I'm able to print "1 2 3 4 5" without race condition using conditional variables and mutexes. But the problem occurs when I try to make it an infinite loop. Can anyone please review my code and suggest the edits I have to make Inorder to get an ouptut like

1 2 3 4 5 1 2 3 4 5 1 2 3 4 5 1 2 3 4 5 1 2 3 4 5 1 2 3 4 5 1 2 3 4 5 1 2 3 4 5 ...

Below is the code which I have tried implementing.

#include <stdio.h>
#include <stdlib.h>
#include <pthread.h>

static int count=0, count2=0, count3=0, count4=0,count5=1;

pthread_cond_t c1 = PTHREAD_COND_INITIALIZER;
pthread_cond_t c2 = PTHREAD_COND_INITIALIZER;
pthread_cond_t c3 = PTHREAD_COND_INITIALIZER;
pthread_cond_t c4 = PTHREAD_COND_INITIALIZER;
pthread_cond_t c5 = PTHREAD_COND_INITIALIZER;
pthread_mutex_t m = PTHREAD_MUTEX_INITIALIZER; //Mutex Variable


void *func1(void *a){
while(1){
            pthread_mutex_lock(&m);
            while(count5 == 0){
                pthread_cond_wait(&c5, &m);
            }
            printf("1 ");
            count = 1;
            count5 = 0;
            pthread_cond_signal(&c1);
            pthread_mutex_unlock(&m);
}
}

void *func2(void *b){
while(1){
        pthread_mutex_lock(&m);
        while(count == 0){
            pthread_cond_wait(&c1, &m);
        }
        printf("2 ");
        count2 = 1;
        pthread_cond_signal(&c2);
        pthread_mutex_unlock(&m);
}
}

void *func3(void *c){
while(1){
        pthread_mutex_lock(&m);
        while(count2 == 0){
            pthread_cond_wait(&c2, &m);
        }
        printf("3 ");
        count3 = 1;
        pthread_cond_signal(&c3);
        pthread_mutex_unlock(&m);
}
}

void *func4(void *d){
while(1){
        pthread_mutex_lock(&m);
        while(count3 == 0){
            pthread_cond_wait(&c3, &m);
        }
        printf("4 ");
        count4 = 1;
        pthread_cond_signal(&c4);
        pthread_mutex_unlock(&m);
}
}

void *func5(void *e){
while(1){
        pthread_mutex_lock(&m);
        while(count4 == 0){
            pthread_cond_wait(&c4, &m);
        }
        printf("5 ");
        count=0;
        count2=0;
        count3=0;
        count4=0;
        count5=1;
        pthread_cond_signal(&c5);
        pthread_mutex_unlock(&m);
}
}

int main(int argc, char **argv){
    pthread_t thread[5];

    pthread_create(&thread[0], NULL, func1, NULL);
    pthread_create(&thread[1], NULL, func2, NULL);
    pthread_create(&thread[2], NULL, func3, NULL);
    pthread_create(&thread[3], NULL, func4, NULL);
    pthread_create(&thread[4], NULL, func5, NULL);

    for(int i=0; i<5; i++)
        pthread_join(thread[i], NULL);

    pthread_mutex_destroy(&m);
    pthread_cond_destroy(&c1);
    pthread_cond_destroy(&c2);
    pthread_cond_destroy(&c3);
    pthread_cond_destroy(&c4);

    pthread_exit(NULL);

    return 0;
}
\$\endgroup\$
  • \$\begingroup\$ what does the posted code output? Why the loop calling pthread_join()? why the calls to pthread_cond_destroy()? why the call to pthread_mutex_destroy()? Suggest each thread near the bottom of the loop, call pthread_cond_signal() for the NEXT thread. Suggest elimination of the count# variables as they are just cluttering the code \$\endgroup\$ – user3629249 Sep 8 '16 at 16:37
  • \$\begingroup\$ for ease of understanding and readability, consistenly indent the code. indent after every opening brace '{'. unindent before every closing brace '}'. \$\endgroup\$ – user3629249 Sep 8 '16 at 16:40
  • \$\begingroup\$ Can anyone please mention why this question has been put on hold? Now I'm not able to answer my own question as I have got the correct output. \$\endgroup\$ – Vishnu N K Sep 9 '16 at 9:03
1
\$\begingroup\$

the following code does not start the output successfully every time, for which I'm not sure of the reason.

I'll let you debug that detail.

#include <stdio.h>
#include <stdlib.h>
#include <pthread.h>
#include <unistd.h> // sleep()

pthread_cond_t c1 = PTHREAD_COND_INITIALIZER;
pthread_cond_t c2 = PTHREAD_COND_INITIALIZER;
pthread_cond_t c3 = PTHREAD_COND_INITIALIZER;
pthread_cond_t c4 = PTHREAD_COND_INITIALIZER;
pthread_cond_t c5 = PTHREAD_COND_INITIALIZER;
pthread_mutex_t m = PTHREAD_MUTEX_INITIALIZER; //Mutex Variable


void *func1(void *a)
{
    (void)a;

    while(1)
    {
        pthread_cond_wait(&c1, &m);

        printf("1 ");

        pthread_cond_signal(&c2);
    }
}

void *func2(void *b)
{
    (void)b;

    while(1)
    {
        pthread_cond_wait(&c2, &m);

        printf("2 ");

        pthread_cond_signal(&c3);
    }
}

void *func3(void *c)
{
    (void)c;

    while(1)
    {
        pthread_cond_wait(&c3, &m);

        printf("3 ");

        pthread_cond_signal(&c4);
    }
}

void *func4(void *d)
{
    (void)d;

    while(1)
    {
        pthread_cond_wait(&c4, &m);

        printf("4 ");

        pthread_cond_signal(&c5);
    }
}

void *func5(void *e)
{
    (void)e;

    while(1)
    {
        pthread_cond_wait(&c5, &m);

        printf("5 ");

        pthread_cond_signal(&c1);
    }
}

int main( void )
{
    pthread_t thread[5];

    pthread_create(&thread[0], NULL, func1, NULL);
    pthread_create(&thread[1], NULL, func2, NULL);
    pthread_create(&thread[2], NULL, func3, NULL);
    pthread_create(&thread[3], NULL, func4, NULL);
    pthread_create(&thread[4], NULL, func5, NULL);

    // get the ball rolling...
    pthread_cond_signal( &c1 );

    while(1)
        sleep(10);

    // never gets here
    return 0;
}
\$\endgroup\$

Not the answer you're looking for? Browse other questions tagged or ask your own question.