Pthreads & Signals.
Jerry Feldman
gerald.feldman at hp.com
Thu Nov 18 08:19:40 EST 2004
On Wednesday 17 November 2004 11:02 am, Anthony Gabrielson wrote:
> Okay,
> With the help of several I got it working and clarifed my
> inderstanding on how pthreads work. So anyway I have it working and if
> anyone is curious I attached it.
I just want to followup with a final note.
WRT: pthrsignal_V2.c
In Main line 43 youn try to lock the mutex after the condition wait:
result = pthread_cond_wait( &got_data, &guard_revc );
:
:
result = pthread_mutex_lock( &guard_revc ); BAD
pthread_cond_wait() is called with a locked mutex. It unlocks the mutex
allowing other threads to proceed, and then when it returns the mutex is
relocked. So in this case you are locking the mutex twice. If the mutex was
a recursive mutex, that would cause some interesting problems.
In function thr:
result = pthread_mutex_lock( &guard_revc ); a.
printf("thr: Got Mutex %d\n",result);
usleep(1);
result = pthread_mutex_unlock( &guard_revc ); b.
printf("thr: Release Mutex %d\n",result);
result = pthread_cond_signal( &got_data ); c.
a. Good place to acquire a lock except that you don't want to acquire it
before it is necessary. There is no reason to acquire a lock before
usleep() or printf().
b. Very bad. The mutex should be locked BEFORE calling pthread_cond_wait.
See my explanation above.
WRT: While loops. They accomplsh nothing.
Lock is initialized to 0. You loop on it, call pthread_cond_wait(), then you
unconditionally set lock to 1. It appears you are trying to synchronize
with main, but if you had set your mutexes correctly, like in the code I
sent you, you would not need that.
And, last of all, after you complete pthread_cond_wait() you FAIL to unlock
the mutex. This exits the thread with a locked mutex causing a potential
deadlock. As I mentioned yesterday, in main(), lock the mutex before
calling pthread_create. This will cause thr() to block on entry before it
calls pthread_cond_signal(). Then you enter the pthread_cond_wait() which
unlocks the mutex allowing thr() to run. Thr() then signals the condition
causing main() to wake up and block on the mutex (before exiting its
cond_wait). Thr then enters its cond_wait, unlocking the mutex as it
enters. Main now returns from cond_wait. It unlocks its mutex, signals the
condition and joins. Thr() now wakes up, reacquires the mutex (implicitly
by cond_wait), then releases the mutex and exits.
Here is some pseudo code (with printfs et. al eliminated)
Main: child:
lock mutex
create child locks mutex - is blocked.
wait on condition (mutex is implicitly unlocked) child now can run
condition complete, blocks on mutex signal condition
(cond reacquires mutex implicitly) waits on condition
(mutex is unlocked)
Unlock mutex (no affect on child)
issues signal to cond. returns from cond
Waits on join. unlocks mutex
return (pthread_exit)
program completes/
Some other things to remember. You should maintain a locked mutex for as
short a time as possible. In this case, your lock variable is useless. But,
let's way you have a worker thread that wants to get data from a queue:
worker:
lock mutex.
Are there elements on the queue <<<<<--------+
yes -- Remove the next element ^
unlock the mutex |
process that element. |
continue. |
|
no -- Wait on condition. |
---------------------------------->>>>> +
done:
unlock mutex.
return.
--
Jerry Feldman <gerald.feldman at hp.com>
Partner Technology Access Center (contractor) (PTAC-MA)
Hewlett-Packard Co.
550 King Street LKG2a-X2
Littleton, Ma. 01460
(978)506-5243
More information about the Discuss
mailing list