1

I'm invoking 100 threads, and each threads should increment a shared variable 1000 times. So the expected output should be 100000. Of course when multiple threads try to increment one shared variable, you can also get outputs that are not 100000 (it's not very likely that you can get 100000).

To deal with this, I put a lock in the method that increments the variable so that everything runs synchronously.

However, I'm still getting numbers like 99000, 98000, and sometimes 100000. But it should always be 100000 because I have a lock right?

This is what I have

volatile unsigned int count = 0;

void *increment(void *vargp);
pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER;

int main() {
    fprintf(stdout, "Before: count = %d\n", count);

    int j;
    // run 10 times to test output
    for (j = 0; j < 10; j++) {
        // reset count every time
        count = 0;

        int i;
        // create 100 theads
        for (i = 0; i < 100; i++) {
            pthread_t thread;

            Pthread_create(&thread, NULL, increment, NULL);
        }

        fprintf(stdout, "After: count = %d\n", count);
    }

    return 0;
}          

void *increment(void *vargp) {
    int c;

    // protected by mutex lock
    pthread_mutex_lock(&mutex);

    // increment count 1000 times
    for (c = 0; c < 1000; c++) {
        count++;
    }

    pthread_mutex_unlock(&mutex);

    return NULL;
}    
PTN
  • 1,658
  • 5
  • 24
  • 54

2 Answers2

5

Are you waiting for all the threads to finish? Doesn't look like you are. Try something like How can I wait for any/all pthreads to complete?

Community
  • 1
  • 1
David Neiss
  • 8,161
  • 2
  • 20
  • 21
2

the following code, run on ubuntu linux 14.04 compiles cleanly and performs correctly.

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

#define UNUSED(x)      (void)(x)
#define NUM_TESTS      (10)
#define NUM_INCREMENTS (1000)
#define NUM_THREADS    (100)

volatile unsigned int count = 0;

void *increment(void *vargp);

pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER;

int main( void )
{
    fprintf(stdout, "Before: count = %d\n", count);

    pthread_t thread[NUM_THREADS];
    int j;

    // run 10 times to test output
    for (j = 0; j < NUM_TESTS; j++)
    {
        // reset count every time
        count = 0;

        int i;
        // create 100 theads
        for (i = 0; i < NUM_THREADS; i++)
        {
            pthread_create(&thread[i], NULL, increment, NULL);
        }

        for( i=0; i < NUM_THREADS; i++ )
        {
            void *retval;
            pthread_join( thread[i], &retval);
        }

        fprintf(stdout, "After: count = %d\n", count);
    }

    return 0;
}

void *increment(void *vargp)
{
    UNUSED(vargp);
    int c;

    // protected by mutex lock
    pthread_mutex_lock(&mutex);

    // increment count 1000 times
    for (c = 0; c < NUM_INCREMENTS; c++)
    {
        count++;
    }

    pthread_mutex_unlock(&mutex);

    pthread_exit( NULL );
}
user3629249
  • 16,402
  • 1
  • 16
  • 17