LinuxQuestions.org
Share your knowledge at the LQ Wiki.
Go Back   LinuxQuestions.org > Forums > Non-*NIX Forums > Programming
User Name
Password
Programming This forum is for all programming questions.
The question does not have to be directly related to Linux and any language is fair game.

Notices

Reply
 
Search this Thread
Old 06-16-2012, 10:17 AM   #16
Nominal Animal
Senior Member
 
Registered: Dec 2010
Location: Finland
Distribution: Xubuntu, CentOS, LFS
Posts: 1,723
Blog Entries: 3

Rep: Reputation: 942Reputation: 942Reputation: 942Reputation: 942Reputation: 942Reputation: 942Reputation: 942Reputation: 942

Anisha Kaul, there are a few details missing in your explanation. The main one is that ThreadB must also lock the mutex.

Perhaps example code would make it clearer for others? (And do say so if you disagree with the following snippets!)

First, the two threads will need a common mutex and a condition variable, in addition to the counter. The condition variable is used to wake up any waiters. The type of the counter variable doesn't matter. All threads must lock the mutex before accessing the counter.
Code:
int              counter;
pthread_mutex_t  counter_lock = PTHREAD_MUTEX_INITIALIZER;
pthread_cond_t   counter_wait = PTHREAD_COND_INITIALIZER;
When a thread modifies the counter, it should also signal or broadcast on the condition variable to wake up any waiters. Signaling wakes up a random one, and broadcasting wakes up all. Broadcasting causes a bit of a thundering herd among the waiters, so it is not the most efficient option; but usually it is the one you'll need. (You can only rely on signaling instead of broadcasting, if you know all waiters wait for the counter to change. If any of them wait for the counter to change to a specific value, you must use broadcast, to make sure each waiter checks the new counter value.)
Code:
if (pthread_mutex_lock(&counter_lock)) {
    /* Fatal error: Deadlock or damaged mutex! */
    exit(1);
}

/* Modify counter */
counter++;

/* Wake up all threads waiting for the counter to change.
 * Note: pthread_cond_broadcast() never returns an error code. */
pthread_cond_broadcast(&counter_wait);

if (pthread_mutex_unlock(&counter_lock)) {
    /* Fatal error: Damaged mutex! */
    exit(1);
}
In many applications you can omit the error checking for the functions. However, I recommend always checking the pthread_mutex_lock() return value for deadlock.

Let us assume the other thread wishes to wait until the counter reaches a certain value. I personally avoid checking for a specific value using ==, to avoid race conditions: other threads can easily manage to increase the counter twice before a waiting thread gets the mutex!
Code:
if (pthread_mutex_lock(&counter_lock)) {
    /* Fatal error: Deadlock or damaged mutex! */
    exit(1);
}

/* Waiting loop: inspect each counter value, and if not desired yet, wait.
 * Note: pthread_cond_wait() never returns an error. */
while (counter < some_value)
    pthread_cond_wait(&counter_wait, &counter_lock);

/* Okay, counter >= some_value now.
 * Note that the mutex is locked, and we can access counter here.
*/

if (pthread_mutex_unlock(&counter_lock)) {
    /* Fatal error: Damaged mutex! */
    exit(1);
}
 
1 members found this post helpful.
Old 06-19-2012, 03:00 AM   #17
TheIndependentAquarius
Senior Member
 
Registered: Dec 2008
Posts: 4,615
Blog Entries: 29

Original Poster
Rep: Reputation: 896Reputation: 896Reputation: 896Reputation: 896Reputation: 896Reputation: 896Reputation: 896
Thanks for all the details, Nominal.
Quote:
Originally Posted by Nominal Animal View Post
Signaling wakes up a random one
Wasn't aware of this. I thought it is based on the priority or who came first.

Quote:
Originally Posted by Nominal Animal View Post
I personally avoid checking for a specific value using ==, to avoid race conditions: other threads can easily manage to increase the counter twice before a waiting thread gets the mutex!
Code:
if (pthread_mutex_lock(&counter_lock)) {
    /* Fatal error: Deadlock or damaged mutex! */
    exit(1);
}

/* Waiting loop: inspect each counter value, and if not desired yet, wait.
 * Note: pthread_cond_wait() never returns an error. */
while (counter < some_value)
    pthread_cond_wait(&counter_wait, &counter_lock);

/* Okay, counter >= some_value now.
 * Note that the mutex is locked, and we can access counter here.
*/

if (pthread_mutex_unlock(&counter_lock)) {
    /* Fatal error: Damaged mutex! */
    exit(1);
}
and in this example you have locked the mutex, so other threads won't increase the counter twice before a waiting thread gets the mutex? Other threads won't be able to do anything here till this thread releases the mutex? this is what you meant?
 
Old 06-19-2012, 05:19 AM   #18
Nominal Animal
Senior Member
 
Registered: Dec 2010
Location: Finland
Distribution: Xubuntu, CentOS, LFS
Posts: 1,723
Blog Entries: 3

Rep: Reputation: 942Reputation: 942Reputation: 942Reputation: 942Reputation: 942Reputation: 942Reputation: 942Reputation: 942
Quote:
Originally Posted by Anisha Kaul View Post
in this example you have locked the mutex, so other threads won't increase the counter twice before a waiting thread gets the mutex?
The counter can be increased twice or more before a waiting thread gets the mutex. Locking the mutex is necessary to safely read the counter. It also makes sure this thread will not miss a counter change.

Consider the scenario where the other thread will modify the counter one last time. If you do not lock the mutex in this thread, how are you going to notice the counter has changed? This thread could start waiting on the condition variable (using some other mutex) a nanosecond after the other thread broadcasts on it, and would therefore wait forever.

Instead, here, this thread locks the mutex first. Then it can freely examine the counter. No other thread will change the counter value because the mutex is locked. If the counter is not a satisfactory value, this thread waits on the condition variable. That will atomically unlock the mutex. Any thread that will modify the counter will signal first, then release the mutex, so this thread will be woken up, automatically reacquire the mutex, and be guaranteed to notice that the counter has changed.

The reason why the counter may be increased multiple times before any waiters can re-examine the counter is simple: assume two threads who wish to modify the counter try to lock the mutex at just about the same time. Even if the one that got the mutex first does broadcast on the condition variable, the second thread may get to lock the mutex first before the waiting threads.
 
  


Reply

Tags
c++, condition-variables, pthreads


Thread Tools Search this Thread
Search this Thread:

Advanced Search

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is Off
HTML code is Off


Similar Threads
Thread Thread Starter Forum Replies Last Post
[SOLVED] pthread threads and mutex naaman Programming 1 02-07-2011 02:50 AM
Pthread mutex doubt rajesh1978 Programming 2 09-17-2010 09:34 AM
Difference between condition variable and mutex linux_ujjwal Linux - General 4 05-10-2005 03:17 AM
How does pthread_mutex_lock() lock mutex in pthread icoming Programming 0 12-04-2004 08:54 AM
pthread mutex issue gauge73 Programming 6 04-20-2004 05:29 PM


All times are GMT -5. The time now is 03:46 AM.

Main Menu
My LQ
Write for LQ
LinuxQuestions.org is looking for people interested in writing Editorials, Articles, Reviews, and more. If you'd like to contribute content, let us know.
Main Menu
Syndicate
RSS1  Latest Threads
RSS1  LQ News
Twitter: @linuxquestions
identi.ca: @linuxquestions
Facebook: linuxquestions Google+: linuxquestions
Open Source Consulting | Domain Registration