Find the answer to your Linux question:
Results 1 to 4 of 4
Hi guys I have a question about thread programming. Based on the material on the web, I created a simple program that would create a bunch of threads in a ...
  1. #1
    Just Joined!
    Join Date
    Nov 2011
    Posts
    12

    Question about pthreads

    Hi guys

    I have a question about thread programming. Based on the material on the web, I created a simple program that would create a bunch of threads in a loop like this:

    #define N_THREADS 5
    void* thread_function(void*);
    pthread_mutex_t mutex1 = PTHREAD_MUTEX_INITIALIZER;
    int counter = 0;

    int main()
    {
    int i;
    int j;
    int i_ptr=&i;
    pthread_t threads[N_THREADS];

    for(i=0; i < N_THREADS; i++)
    {pthread_create( &threads[i], NULL, thread_function, (void*) i_ptr);
    //sleep (1);}

    for(j=0; j < N_THREADS; j++) pthread_join( threads[j], NULL);

    return (0);
    }

    void* thread_function(void* data)
    {
    pthread_mutex_lock( &mutex1 );
    int thread_data=*(int*)data;
    counter++;
    printf("I am thread number %d Counter value is %d\n",thread_data, counter);
    pthread_mutex_unlock( &mutex1 );
    pthread_exit("NULL");
    }


    When I execute the code above, I should normally get:

    I am thread number 0 Counter value is 1
    I am thread number 1 Counter value is 2
    I am thread number 2 Counter value is 3
    I am thread number 3 Counter value is 4
    I am thread number 4 Counter value is 5

    But instead i get:

    I am thread number 1 Counter value is 1
    I am thread number 5 Counter value is 2
    I am thread number 5 Counter value is 3
    I am thread number 5 Counter value is 4
    I am thread number 5 Counter value is 5

    or

    I am thread number 1 Counter value is 1
    I am thread number 5 Counter value is 3
    I am thread number 2 Counter value is 2
    I am thread number 5 Counter value is 4
    I am thread number 5 Counter value is 5


    or even(!):

    I am thread number 5 Counter value is 1
    I am thread number 5 Counter value is 2
    I am thread number 5 Counter value is 3
    I am thread number 5 Counter value is 4
    I am thread number 5 Counter value is 5



    Counter values seem to be fine, but why is the thread numbers not working properly? When i debug it with gdb, it works fine. When I add the sleep in the first loop, i also get correct output.
    What could be the reason for this weird behavior?

  2. #2
    Linux Newbie
    Join Date
    Mar 2010
    Posts
    121
    Please use code tags for code!

    When you create your thread, you're passing in a pointer to a variable on the stack, and it's the same address for each thread. Since there is no guarantee that threads run immediately or in sequence, your main loop may have (in this case, has) incremented the variable at the location the thread function reads, so changing what the thread function reads.

    The solution is to (a) use a key, (b) in the case of simple data types like the int you're using, cast to and from:

    Code:
    void *thread_func(void *arg)
    {
        int i = (int)arg;
        //
    }
    
    void whatever()
    {
        int i = 1;
        pthread(thread, NULL, &thread_func, (void *)i);
    }
    or (c) use an array of int values so you pass in the address to a different one each time.

  3. #3
    Just Joined!
    Join Date
    Nov 2011
    Posts
    12
    Dear John,
    Thanks for the explanation but it's not so clear from what you've just written. Your modification of the code has worked, but could you explain it more simply and clearly?
    PS. Sorry for the code tags, I am new to the forum

  4. #4
    Linux Newbie
    Join Date
    Mar 2010
    Posts
    121
    Here's a simple "example trace" of the steps your program might take. I've only gone up to just after the launch of the first thread, since this will be enough to demonstrate the problem. Let's assume for simplicity that the i in your main function is located at address 10 (not that it ever will be, but hey...).

    When reading this (and indeed, when dealing with threaded applications) it's important to keep in mind that the OS's thread scheduler very deliberately makes absolutely no guarantees about when which threads will get executed. In particular in your case, it does not guarantee (or even attempt to guarantee) that a newly created thread will have started running/executed any instructions before pthread_create() returns.

    Code:
    /***  In main thread.  ***/
    
    // 'i' declared, and is on the stack
    int i;  // Located at address 10.
    
    // Start our 'for' loop, so i is set to 0.
    i = 0;
    
    // Create the first thread. Remember, there's no guarantee it'll
    // run immediately.
    // Note the value we've passed in is (void *)10.
    pthread_create(&threads[i], NULL, &thread_func, (void *)&i);
    
    // Still in the main thread, i gets incremented.
    i++;  // i is now 1, and thus the value at address 10 is now 1.
    
    /***  Context switch to thread 1  ***/
    // We're now in the first thread - we've started execution in
    // thread_func().
    void *thread_func(void *data) {
    
        // Let's dereference our pointer. It's pointing to address 10,
        // and I guess you know what's there...
        int thread_data=*(int*)data;
    
        // At this point, thread_data is equal to whatever was at
        // address 10 - i.e. 1.

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •  
...