#1
  1. No Profile Picture
    Registered User
    Devshed Newbie (0 - 499 posts)

    Join Date
    Oct 2012
    Posts
    3
    Rep Power
    0

    Thumbs down HELP! Multiple threads access to global variables


    I'm trying to solve the producer consumer problem for multiple producers and consumers using a multi slot buffer.

    I am using a mutex to ensure mutual exclusion when the producer and consumers are accessing the buffers, and a conditional variable to block when the buffer is full or empty.

    The globals are buffer, which is an array of struct 'data' and buffercount, which is an int to keep track of the size of buffer.

    However, I cannot access the variables and my threads stall. This can be seen because though in the producer thread, i create the data and get into the function writeData, which writes the data to the buffer, I cannot print the values of count or write to the buffer in that function, it just stops.

    Below is my code:

    Code:
    #include <pthread.h>
    #include <semaphore.h>
    #include <stdio.h>
    #include <stdlib.h>
    #include <time.h>
    
    
    typedef struct{
    int x,y,z;
    }data;
    
    volatile data buffer[20];
    volatile int count;
    pthread_mutex_t m;
    pthread_cond_t qu_empty_cond = PTHREAD_COND_INITIALIZER;
    pthread_cond_t qu_full_cond = PTHREAD_COND_INITIALIZER;
    
    
    
    void produce();
    void consume();
    void createData(data*);
    void writeBuffer(data);
    void readBuffer(data*);
    void waitRandom();
    void shiftBuffer();
    
    
    int main (){
    pthread_t p, c;
    count = 0;
    
    if(pthread_mutex_init(&m, NULL)){
            printf("mutex creation failed\n");
            return 1;
    }
    else printf("mutex creation sucess\n");
    
    if(pthread_create (&p,NULL,(void *) &produce,NULL)){
            printf("producer creation failed\n");
            return 1;
    }
    
    if (pthread_create (&c,NULL,(void *) &consume,NULL)){
            printf("consumer creation failed\n");
            return 1;
    }
    
    return 0;
    }
    
    void produce(void){
    printf("producer creation success count\n");
    while(1){
            data a;
            createData(&a);
            printf("PRODUCE: checking for mutual exclusion\n");
            pthread_mutex_lock(&m);
            printf("have mutual exclusion to produce\n");
            //if 20 block
            /*while(count>=20){
                    printf("stuck \n");
                    pthread_cond_wait(&qu_full_cond, &m);
                    }*/
            writeBuffer(a);
            //increment
            count++;
            if(count=1)
                    pthread_cond_signal(&qu_empty_cond);
            pthread_mutex_unlock(&m);
            printf("lost mutual exclusion to produce\n");
            waitRandom();
            }
    }
    
    void consume(void){
    printf("consumer creation success \n");
    while(1){
            data a;
            printf("CONSUME: checking for mutual exclusion\n");
            pthread_mutex_lock(&m);
            printf("have mutual exclusion to consume\n");
            //if 0 block
            while(count<=0){
                    printf("stuck\n");
                    waitRandom();
                    pthread_cond_wait(&qu_empty_cond, &m);
                    }
            readBuffer(&a);
            shiftBuffer();
            count--;
            //if 19 release
            if(count=19)
                    pthread_cond_signal(&qu_full_cond);
            pthread_mutex_unlock(&m);
            printf("lost mutual exclusion to consume\n");
            waitRandom();
            }
    }
    
    
    
    void createData(data* a){
            printf("creating data\n");
            a->x=1;
            a->y=2;
            a->z=3;
    }
    
    void writeBuffer(data a){
            printf("inthefunction1111\n");
            printf("writing to buffer slot %d, new size of buffer is %d\n", count, count+1);
            buffer[count] = a;
            printf("%d      %d      %d",buffer[count].x,buffer[count].y,buffer[count].z);
    }
    
    void readBuffer(data* a){
            printf("reading buffer slot 0 \n");
            a->x = buffer[0].x;
            a->y = buffer[0].y;
            a->z = buffer[0].z;
    }
    
    void shiftBuffer(void){
            int i;
            printf("deleting buffer slot 0 \n");
            for(i=0;i<count;i++)
                    buffer[i]=buffer[i+1];
    }
    
    void waitRandom(void){
            srand ( time(NULL) );
            sleep(rand()%2000 + 1000 );
    }
  2. #2
  3. Contributed User
    Devshed Specialist (4000 - 4499 posts)

    Join Date
    Jun 2005
    Posts
    4,379
    Rep Power
    1871
    Does your code have no indentation in your editor as well?

    Your code is impossible to read "as is".

    Please edit your post, and post indented code.
    If you dance barefoot on the broken glass of undefined behaviour, you've got to expect the occasional cut.
    If at first you don't succeed, try writing your phone number on the exam paper
  4. #3
  5. No Profile Picture
    Registered User
    Devshed Newbie (0 - 499 posts)

    Join Date
    Oct 2012
    Posts
    3
    Rep Power
    0
    Fixed

    Originally Posted by salem
    Does your code have no indentation in your editor as well?

    Your code is impossible to read "as is".

    Please edit your post, and post indented code.
  6. #4
  7. Contributed User
    Devshed Specialist (4000 - 4499 posts)

    Join Date
    Jun 2005
    Posts
    4,379
    Rep Power
    1871
    Well did you compile with any warnings enabled?

    Or run the code with any warnings still to be fixed?

    Code:
    $ gcc -Wall foo.c -pthread
    foo.c: In function ‘produce’:
    foo.c:68:9: warning: suggest parentheses around assignment used as truth value [-Wparentheses]
    foo.c: In function ‘consume’:
    foo.c:93:9: warning: suggest parentheses around assignment used as truth value [-Wparentheses]
    foo.c: In function ‘waitRandom’:
    foo.c:133:9: warning: implicit declaration of function ‘sleep’ [-Wimplicit-function-declaration]
    For these
    if(count=1)
    which I guess should be
    if(count==1)
    If you dance barefoot on the broken glass of undefined behaviour, you've got to expect the occasional cut.
    If at first you don't succeed, try writing your phone number on the exam paper
  8. #5
  9. No Profile Picture
    Registered User
    Devshed Newbie (0 - 499 posts)

    Join Date
    Oct 2012
    Posts
    3
    Rep Power
    0
    Thanks for the suggestions!
    I fixed the == operators in the if statements and included unistd.h to fix the problem with sleep. I also added lines to check the return argument of the mutex lock, however I am still having the same problems.

    Below is my updated code.

    Code:
    #include <pthread.h>
    #include <semaphore.h>
    #include <stdio.h>
    #include <stdlib.h>
    #include <time.h>
    #include <unistd.h>
    
    typedef struct{
    int x,y,z;
    }data;
    
    volatile data buffer[20];
    volatile int count;
    pthread_mutex_t m;
    pthread_cond_t qu_empty_cond = PTHREAD_COND_INITIALIZER;
    pthread_cond_t qu_full_cond = PTHREAD_COND_INITIALIZER;
    
    
    
    void produce();
    void consume();
    void createData(data*);
    void writeBuffer(data);
    void readBuffer(data*);
    void waitRandom();
    void shiftBuffer();
    
    
    int main (){
    pthread_t p, c;
    count = 0;
    
    if(pthread_mutex_init(&m, NULL)){
            printf("mutex creation failed\n");
            return 1;
    }
    else printf("mutex creation sucess\n");
    
    if(pthread_create (&p,NULL,(void *) &produce,NULL)){
            printf("producer creation failed\n");
            return 1;
    }
    
    if (pthread_create (&c,NULL,(void *) &consume,NULL)){
            printf("consumer creation failed\n");
            return 1;
    }
    
    return 0;
    }
    
    void produce(void){
    printf("producer creation success count\n");
    while(1){
            data a;
            createData(&a);
            printf("PRODUCE: checking for mutual exclusion\n");
            if(pthread_mutex_lock(&m))
                    printf("MUTEX lock in PRODUCER failed, blocking until MUTEX is available \n");
            else
            printf("have mutual exclusion to produce\n");
            //if 20 block
            /*while(count>=20){
                    printf("stuck \n");
                    pthread_cond_wait(&qu_full_cond, &m);
                    }*/
            writeBuffer(a);
            //increment
            count++;
            if(count==1)
                    pthread_cond_signal(&qu_empty_cond);
            pthread_mutex_unlock(&m);
            printf("lost mutual exclusion to produce\n");
            waitRandom();
            }
    }
    
    void consume(void){
    printf("consumer creation success \n");
    while(1){
            data a;
            printf("CONSUME: checking for mutual exclusion\n");
            if(pthread_mutex_lock(&m))
                    printf("MUTEX lock in CONSUMER failed, blocking until MUTEX is available \n");
            else
                    printf("have mutual exclusion to consume\n");
            //if 0 block
            while(count<=0){
                    printf("stuck\n");
                    waitRandom();
                    pthread_cond_wait(&qu_empty_cond, &m);
                    }
            readBuffer(&a);
            shiftBuffer();
            count--;
            //if 19 release
            if(count==19)
                    pthread_cond_signal(&qu_full_cond);
            pthread_mutex_unlock(&m);
            printf("lost mutual exclusion to consume\n");
            waitRandom();
            }
    }
    
    
    
    void createData(data* a){
            printf("creating data\n");
            a->x=1;
            a->y=2;
            a->z=3;
    }
    
    void writeBuffer(data a){
            printf("inthefunction1111\n");
            printf("writing to buffer slot %d, new size of buffer is %d\n", count, count+1);
            buffer[count] = a;
            printf("%d      %d      %d",buffer[count].x,buffer[count].y,buffer[count].z);
    }
    
    void readBuffer(data* a){
            printf("reading buffer slot 0 \n");
            a->x = buffer[0].x;
            a->y = buffer[0].y;
            a->z = buffer[0].z;
    }
    
    void shiftBuffer(void){
            int i;
            printf("deleting buffer slot 0 \n");
            for(i=0;i<count;i++)
                    buffer[i]=buffer[i+1];
    }
    
    void waitRandom(void){
            srand ( time(NULL) );
            sleep(rand()%2000 + 1000 );
    }

IMN logo majestic logo threadwatch logo seochat tools logo