Pergunta

I am trying to use pthread mutex variables and barrier to synchronize the output of my program, but it is not working the way I want it to. Each thread is seeing its final value every 20 values (coming from the for loop) which is alright but I'm trying to make them all get to the same final value (if using 5 threads, all of them should see 100 as final value, with 4 threads, 80, etc)

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

pthread_mutex_t mutex1 = PTHREAD_MUTEX_INITIALIZER;

int SharedVariable =0;
void *SimpleThread(void *args)
{
    int num,val,rc;
    int which =(int)args;
    rc = pthread_mutex_lock(&mutex1);
    for(num=0; num<20; num++){
#ifdef PTHREAD_SYNC
        if(random() > RAND_MAX / 2)
            usleep(10);
#endif
        //pthread_mutex_lock(&mutex1);
        val = SharedVariable;
        printf("*** thread %d sees value %d\n", which, val);
        //pthread_mutex_lock(&mutex1);
        SharedVariable = val+1;
        pthread_mutex_unlock(&mutex1);
    }   
    val=SharedVariable;

    printf("Thread %d sees final value %d\n", which, val);
    //pthread_mutex_destroy(&mutex1);
    //pthread_exit((void*) 0);
    //pthread_mutex_unlock(&mutex1);

}

int main (int argc, char *argv[])
{
   if(atoi(argv[1]) > 0){        
   int num_threads = atoi(argv[1]);  
   //pthread_mutex_init(&mutex1, NULL);
   pthread_t threads[num_threads];
   int rc;
   long t;
   rc = pthread_mutex_lock(&mutex1);
   for(t=0; t< num_threads; t++){
      printf("In main: creating thread %ld\n", t);
      rc = pthread_create(&threads[t], NULL, SimpleThread, (void* )t);
      if (rc){
         printf("ERROR; return code from pthread_create() is %d\n", rc);
         exit(-1);
      }

    //pthread_join(thread1);

   }
    rc= pthread_mutex_unlock(&mutex1);
}
   else{
      printf("ERROR: The parameter should be a valid positive number.");
      exit(-1);
  }

   pthread_mutex_destroy(&mutex1);
   pthread_exit(NULL);
}

Any suggestions or help is greatly appreciated! Thanks in advanced!

Foi útil?

Solução

You need to use a barrier (pthread_barrier_wait()) before checking for the final value - this ensures that no thread will proceed until all threads have reached the barrier.

In addition, you should be calling pthread_join() to wait for the threads to finish, and you only need to hold the mutex around the increment:

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

pthread_mutex_t mutex1 = PTHREAD_MUTEX_INITIALIZER;
pthread_barrier_t barrier1;

int SharedVariable = 0;

void *SimpleThread(void *args)
{
    int num,val;
    int which = (int)args;

    for(num = 0; num < 20; num++) {
#ifdef PTHREAD_SYNC
        if(random() > RAND_MAX / 2)
            usleep(10);
#endif
        pthread_mutex_lock(&mutex1);
        val = SharedVariable;
        printf("*** thread %d sees value %d\n", which, val);
        SharedVariable = val + 1;
        pthread_mutex_unlock(&mutex1);
    }

    pthread_barrier_wait(&barrier1);

    val = SharedVariable;
    printf("Thread %d sees final value %d\n", which, val);
    return 0;
}

int main (int argc, char *argv[])
{
    int num_threads = argc > 1 ? atoi(argv[1]) : 0;

    if (num_threads > 0) {
        pthread_t threads[num_threads];
        int rc;
        long t;

        rc = pthread_barrier_init(&barrier1, NULL, num_threads);

        if (rc) {
            fprintf(stderr, "pthread_barrier_init: %s\n", strerror(rc));
            exit(1);
        }

        for (t = 0; t < num_threads; t++) {
            printf("In main: creating thread %ld\n", t);
            rc = pthread_create(&threads[t], NULL, SimpleThread, (void* )t);
            if (rc) {
                printf("ERROR; return code from pthread_create() is %d\n", rc);
                exit(-1);
            }
        }

        for (t = 0; t < num_threads; t++) {
            pthread_join(threads[t], NULL);
        }
    }
    else {
        printf("ERROR: The parameter should be a valid positive number.\n");
        exit(-1);
    }

    return 0;
}

Outras dicas

Try to move the pthread_mutext_unlock(&mutext1) out of the for loop in your SimpleThread. You lock once and unlock mutiple(20) times in your original code.

Alternatively, you could move pthread_mutex_lock(&mutext1) into the for loop, just before you read and modify your SharedVariable. In this case, each thread's add-by-one operation may not consecutive but each thread will get the correct final value.

And before you read the final value of the SharedVariable, use a barrier to wait all the threads finish their job.

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top