Solving C Threads "Balance" Problem

  • Thread starter James889
  • Start date
  • Tags
    Threads
And now my book is wrong too. It is wrong in such a way that I can't just say "oh, the idiot author got that wrong again".I guess my point is: I've been doing this for years, and I still have trouble with threading :(In summary, the conversation discusses issues with the code that uses pthreads to increase the variable Balance in two threads, but the final Balance remains equal to the initial value. Suggestions are made to check for errors, link against the pthread library, and use print statements for debugging. It is also noted that the function pointer passed into pthread_create should have a type of void* (*)(void*). The importance of using proper examples and references is emphasized.
  • #1
James889
192
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
  • #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:
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:
  • #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:
thread1_id = pthread_create(&thread1,NULL,[COLOR="Red"](void *)[/COLOR]&ThreadRoutine1,NULL);
thread2_id = pthread_create(&thread2,NULL,[COLOR="Red"](void *)[/COLOR]&ThreadRoutine2,NULL);
 
  • #4
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:
  • #5
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)
 
  • #6
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.
 

FAQ: Solving C Threads "Balance" Problem

What is the "Balance" problem in C threads?

The "Balance" problem in C threads refers to the challenge of ensuring that multiple threads accessing a shared resource (such as a variable or data structure) do so in a synchronized and orderly manner, in order to avoid race conditions and other errors.

Why is solving the "Balance" problem important in C threads?

Solving the "Balance" problem is important because it ensures the correct and consistent behavior of a program that uses threads. Without proper synchronization and management of shared resources, the program may produce incorrect results or even crash.

What are some common solutions to the "Balance" problem in C threads?

There are several common solutions to the "Balance" problem in C threads, including using mutexes, semaphores, and condition variables to control access to shared resources. Other techniques include using atomic operations and thread-safe data structures.

What are some potential challenges or drawbacks of solving the "Balance" problem in C threads?

One challenge of solving the "Balance" problem in C threads is ensuring that the synchronization mechanisms are used correctly and efficiently, as improper use can lead to deadlocks or performance issues. Additionally, debugging and troubleshooting issues related to thread synchronization can be complex and time-consuming.

How can I improve my understanding and skills in solving the "Balance" problem in C threads?

To improve your understanding and skills in solving the "Balance" problem in C threads, it is important to have a solid understanding of threading concepts and techniques, as well as debugging and troubleshooting skills. Practicing with different examples and scenarios can also help improve your proficiency in solving this problem.

Back
Top