-
pthread_mutex problem
Hi All,
Consider this [multi-threaded] code fragment...
Code:
int volatile num_threads = 0;
snip...
if(num__threads < MAX_NUM_THREADS)
{
//mutex
pthread_mutex_lock(&my_thread_mutex);
//increment number of used threads
num_threads++;
pthread_mutex_unlock(&my_thread_mutex);
//mutex
printf("%d:DEBUG: num threads = %d\n",pthread_self(),num_threads);
//do work
if(do_work() < 0)
{
//mutex
pthread_mutex_lock(&my_thread_mutex);
//decrement number of slaves
num_threads--;
pthread_mutex_unlock(&my_thread_mutex);
//mutex
return 1;
}
//mutex
pthread_mutex_lock(&my_thread_mutex);
//decrement number of slaves
num_threads--;
pthread_mutex_unlock(&my_thread_mutex);
//mutex
return 0;
}
I'm trying to throttle the number of pthreads accessing this bit of code. The mutexes are initialised and destroyed elsewhere.
The problem is that num_threads ends up negative i..e somehow the decrement is happening more than the increment.
Can anyone see why?
Are my mutexes used correctly?
Thanks for any help,
rotis23
-
It looks fine. Is num__threads being modified anywhere else? By the way, I recommend the following small change:
Code:
int volatile num_threads = 0;
snip...
if(num__threads < MAX_NUM_THREADS)
{
int result;
//mutex
pthread_mutex_lock(&my_thread_mutex);
//increment number of used threads
num_threads++;
pthread_mutex_unlock(&my_thread_mutex);
//mutex
printf("%d:DEBUG: num threads = %d\n",pthread_self(),num_threads);
//do work
result = do_work();
//mutex
pthread_mutex_lock(&my_thread_mutex);
//decrement number of slaves
num_threads--;
pthread_mutex_unlock(&my_thread_mutex);
//mutex
if (result < 0)
return 1;
else
return 0;
}
-
Thanks for the input.
num__threads should be num_threads in my code fragment.
num_threads does not change anywhere else.
Was thinking of doing that change - much more readable ;)
BTW - this is running on an *old* redhat 8.0 platform: any bugs on that platform that would cause this? <clutching at straws>
-
Something very weird going on here...I've seen the debug printf line output MAX_NUM_THREADS+1 !
How is that possible? Either I've implemented the mutexes wrong or they're not working properly.
-
RH8 [ all distros with the 2.4 kernel actually ] had a few small problems with libpthread, that were fixed in the 2.6 kernel.
you my be hitting one of the known issues of the 2.4 kernel with pthreads.
-
I doubt if there were issues with the mutexes in Redhat 8. Maybe other areas, but I bet the mutexes were fairly solid. Anyway, I can see why you would end up with MAX_THREADS+1. Look at the code. You are doing your conditional check on the num_threads outside of the mutex. Do you see why that is a problem? Imagine that you are sitting at num_threads = MAX_THREADS-1 currently. Then thread1 comes along. It says, num_threads less than max, I can continue. Then context switch happens, and control goes to thread2. It looks at num_threads, says num_threads is less than max, I can continue. So then each thread obtains the mutex and increments num_threads. Now you have num_threads == MAX_THREADS+1. So change the logic to something like:
Code:
pthread_mutex_lock(&mutex);
if (num_threads > MAX) {
num_threads++;
// do work
}
else {
pthread_mutex_unlock(&mutex);
}
-
Yes thanks - I can see MAX_THREADS+1 but not num_threads < 0.
-
Is that your real code? I don't see how that code alone can generate a num_threads value less than zero.
-
I think this might have been a memory violation issue. I was attempting to access a NULL struct later in the thread and I'm guessing this could have potentially violated memory?
-
Anytime you attempt to dereference invalid data, strange things can (and usually do) happen in your program.