1. Limited time only! Sign up for a free 30min personal tutor trial with Chegg Tutors
    Dismiss Notice
Dismiss Notice
Join Physics Forums Today!
The friendliest, high quality science and math community on the planet! Everyone who loves science is here!

C threads question

  1. Jul 3, 2011 #1
    Hi,

    I've recently started C and i have a quick question

    in the code below i increase the variable Balance in two threads, but somehow the final Balance is still equal to the initial value. Why?
    Code (Text):

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



    pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER;

    int Balance = 100;

    void *ThreadRoutine1(void) {

        pthread_mutex_lock(&mutex);
        Balance++;
        pthread_mutex_unlock(&mutex);
        printf("Balance is now:%d\n",Balance);
        pthread_exit(NULL);
    }

    void *ThreadRoutine2(void) {

            pthread_mutex_lock(&mutex);
            Balance++;
            pthread_mutex_unlock(&mutex);
            printf("Balance is now:%d\n",Balance);
            pthread_exit(NULL);

    }

    int main() {

            pthread_t thread1,thread2;
            int thread1_id;
            int thread2_id;


            thread1_id = pthread_create(&thread1,NULL,(void *)ThreadRoutine1,NULL);
            thread2_id = pthread_create(&thread2,NULL,(void *)ThreadRoutine2,NULL);

            pthread_join(&thread1,NULL);
            pthread_join(&thread2,NULL);

            printf("Final Balance is:%d\t",Balance);
    }
     
     
  2. jcsd
  3. Jul 3, 2011 #2
    Your pointers are out of whack. For example, your thread functions should return void (EDIT: that's badly put - let's say "should have a return type of void"), not void*. If a function requires a void*, then use the & operator.

    And make sure you don't pass a pointer when the function doesn't expect one.

    Anyways, note you aren't getting output from the printf's in your thread functions. They are not being run.

    Define your thread functions like this:
    Code (Text):

    void ThreadRoutine1(void) {
     
    The creates should look like this:

    Code (Text):


            thread1_id = pthread_create(&thread1,NULL,(void *)&ThreadRoutine1,NULL);
            thread2_id = pthread_create(&thread2,NULL,(void *)&ThreadRoutine2,NULL);
     
    And also your joins are wrong and should look like this:
    Code (Text):

            pthread_join(thread1,NULL);
            pthread_join(thread2,NULL);
     
    In these kind of cases, pay a lot of attention to the warnings you're getting. Make sure you compile with -Wall to get all warnings. For example, you're missing the return at the end of main. So add 'return 0;' at the end of it.

    After those fixes, it works and compiles without warnings for me. Hope that helps!
     
    Last edited: Jul 3, 2011
  4. Jul 4, 2011 #3
    I never really understood (in my case) why you have to type cast the ThreadRoutine to void * when it already is of the type void *.
    Code (Text):
    thread1_id = pthread_create(&thread1,NULL,[COLOR="Red"](void *)[/COLOR]&ThreadRoutine1,NULL);
    thread2_id = pthread_create(&thread2,NULL,[COLOR="Red"](void *)[/COLOR]&ThreadRoutine2,NULL);
     
     
  5. Jul 4, 2011 #4

    Hurkyl

    User Avatar
    Staff Emeritus
    Science Advisor
    Gold Member

    No, that's wrong. The function pointer passed into pthread_create is supposed to have type
    void* (*)(void*)
    That is, a pointer to a function that returns void* and takes as argument a void*. For example
    Code (Text):

    void* myfunc(void *p)
    {
      printf("In myfunc!");
      return NULL;
    }

    int main()
    {
      pthread_t th;
      pthread_create(&th, NULL, &myfunc, NULL);
      pthread_join(th, NULL);
    }
    The return value of the function can be obtained when you invoke pthread_join.


    Similarly, this is not the right way to do things. Any success you've had is due to the following three things:
    1. C allows implicit conversion from void* to other pointer types
    2. You weren't using C++ (which would complain about the conversion)
    3. You are fortunate enough to be running in an environment that doesn't crash your program when the pthread library invokes your function thinking it takes and returns a void*



    This is right, though.
     
    Last edited: Jul 4, 2011
  6. Jul 4, 2011 #5

    Hurkyl

    User Avatar
    Staff Emeritus
    Science Advisor
    Gold Member

    Did you remember to link against the pthread library? e.g. in a unix system, this would usually require putting "-lpthread" on your link line.

    Did you do any debugging? For example, putting a print statement in your functions (at the top!) to see if they're even getting that far?



    Aside: the pthread library is not part of the C library, and there are other threading libraries available. Your thread would have been better named as something like "C pthreads question".

    Another aside: pthread_create doesn't return a "thread identifier" like it appears you think it does. It returns whether or not there were any errors creating the thread. (the return value will be 0 if and only if there was no error)
     
  7. Jul 4, 2011 #6
    Ouch, thanks for catching that, Hurkyl. Had to refresh my memory on pthreads (been using Qt and Boost threads). First tried to get the man page for pthread_create, but oddly, I don't have it. Then checked for an example with Google, and wouldn't you know the example was wrong (and the compiler silent :frown:). Man page would have given me the right signature. In short, I will now investigate why the darn man page is missing. That and be more careful with where I get my examples! Sheesh.
     
Know someone interested in this topic? Share this thread via Reddit, Google+, Twitter, or Facebook




Similar Discussions: C threads question
  1. C/C++ hw question! (Replies: 3)

  2. C++ question (Replies: 1)

Loading...