Solving C Threads "Balance" Problem

  • Thread starter Thread starter James889
  • Start date Start date
  • Tags Tags
    Threads
Click For Summary

Discussion Overview

The discussion revolves around a C programming issue related to multithreading using the pthread library. Participants are examining why a variable, Balance, does not reflect expected changes after being modified in multiple threads. The conversation includes technical explanations, code corrections, and debugging suggestions.

Discussion Character

  • Technical explanation
  • Debate/contested
  • Exploratory

Main Points Raised

  • One participant questions why the final Balance remains unchanged despite increments in two threads, suggesting potential issues with thread function execution.
  • Another participant points out that thread functions should have a return type of void, not void*, and suggests using the & operator when passing function pointers to pthread_create.
  • A different participant expresses confusion about the necessity of type casting the thread routine to void* when it is already of that type.
  • One participant clarifies that the function pointer for pthread_create should indeed be of type void* (*)(void*), emphasizing the importance of correct function signatures.
  • Another participant raises the need to ensure that the pthread library is linked correctly and suggests adding print statements for debugging purposes.
  • There is a mention that pthread_create does not return a thread identifier but rather an error code indicating success or failure.

Areas of Agreement / Disagreement

Participants express differing views on the correct function signatures and the necessity of type casting. There is no consensus on the best approach to resolve the initial problem regarding the Balance variable, and multiple perspectives on coding practices are presented.

Contextual Notes

Some participants note the importance of compiling with warnings enabled to catch potential issues. There is also mention of missing documentation for pthreads, which may affect understanding and implementation.

James889
Messages
190
Reaction score
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:
#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);
}
 
Physics news on Phys.org
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:
void ThreadRoutine1(void) {

The creates should look like this:

Code:
        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:
        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:
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:
thread1_id = pthread_create(&thread1,NULL,(void *)&ThreadRoutine1,NULL);
thread2_id = pthread_create(&thread2,NULL,(void *)&ThreadRoutine2,NULL);
 
Grep said:
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.
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:
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.


Code:
        thread1_id = pthread_create(&thread1,NULL,(void *)&ThreadRoutine1,NULL);
        thread2_id = pthread_create(&thread2,NULL,(void *)&ThreadRoutine2,NULL);
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*



Code:
 pthread_join(thread1,NULL);
This is right, though.
 
Last edited:
James889 said:
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?
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)
 
Hurkyl said:
No, that's wrong. The function pointer passed into pthread_create is supposed to have type
void* (*)(void*)

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.
 

Similar threads

  • · Replies 1 ·
Replies
1
Views
11K
  • · Replies 1 ·
Replies
1
Views
2K
  • · Replies 17 ·
Replies
17
Views
3K
  • · Replies 12 ·
Replies
12
Views
3K
Replies
1
Views
4K
  • · Replies 8 ·
Replies
8
Views
3K
  • · Replies 2 ·
Replies
2
Views
6K
Replies
1
Views
2K
  • · Replies 3 ·
Replies
3
Views
2K
  • · Replies 2 ·
Replies
2
Views
3K