|
Boost Users : |
Subject: Re: [Boost-users] wait/notify problem
From: girish hilage (girish_hilage_at_[hidden])
Date: 2010-01-18 08:00:40
Hi Gottlob,
Thanks for your reply.
I had written below code for this.
void enable_flag (boost::mutex &mut, bool &flag)
{
mut.lock ();
flag = 1;
mut.unlock ();
}
void mywait (boost::condition_variable &cond, boost::mutex &mut, bool &flag)
{
boost::mutex tmp_mutex;
boost::unique_lock<boost::mutex> lock(tmp_mutex);
enable_flag (mut, flag);
cond.wait (lock);
}
void notify_until_success (boost::condition_variable &cond, boost::mutex &mut, bool &flag)
{
for (;;)
{
usleep (500);
mut.lock ();
if (flag == 1)
{
cond.notify_one();
flag = 0;
mut.unlock ();
break;
}
mut.unlock ();
}
}
But, the mistake I had done was, creation of 'tmp_mutex' inside mywait() and also I had not carefully read the documentation on wait() which says "Atomically call lock.unlock() and blocks the current thread."
I read this while browsing for scoped_lock().
The code I have now written is as follows (which seems to work fine) :
void enable_flag (boost::mutex &mut, bool &flag)
{
mut.lock ();
flag = 1;
mut.unlock ();
}
void mywait (boost::condition_variable &cond, boost::mutex &mut, boost::mutex &flag_mut, bool &flag)
{
boost::unique_lock<boost::mutex> lock(mut);
enable_flag (flag_mut, flag);
cond.wait (lock);
}
void notify_until_success (boost::condition_variable &cond, boost::mutex &mut, boost::mutex &flag_mut, bool &flag)
{
for (;;)
{
mut.lock ();
flag_mut.lock ();
if (flag == 1)
{
cond.notify_one();
flag = 0;
flag_mut.unlock ();
mut.unlock ();
break;
}
flag_mut.unlock ();
mut.unlock ();
}
}
void worker_function (void)
{
for (;;)
{
/* wait for the new job */
mywait (new_job_condition, new_job_mutex, new_job_notification_reached_flag_mutex, new_job_notification_reached_flag);
..... read new job .....
..... do the work .....
/* notify job done */
notify_until_success (job_done_condition, job_done_mutex, job_done_notification_reached_flag_mutex, job_done_notification_reached_flag);
}
}
int main (void)
{
..... create worker threads .....
while (/*there is work to be done */)
{
/* notify any one of the free threads about new_job */
notify_until_success (new_job_condition, new_job_mutex, new_job_notification_reached_flag_mutex, new_job_notification_reached_flag);
/* wait for job_done notification from any of the busy thread */
mywait (job_done_condition, job_done_mutex, job_done_notification_reached_flag_mutex, job_done_notification_reached_flag);
}
}
I hope this will not create any problems.
(I have also edited the problem statement in the mail below to make it more clear. Shown by __TEXT_EDITED__.)
Regards,
Girish
--- On Fri, 1/15/10, Gottlob Frege <gottlobfrege_at_[hidden]> wrote:
From: Gottlob Frege <gottlobfrege_at_[hidden]>
Subject: Re: [Boost-users] wait/notify problem
To: boost-users_at_[hidden]
Date: Friday, January 15, 2010, 4:59 PM
On Fri, Jan 15, 2010 at 4:09 AM, girish hilage <girish_hilage_at_[hidden]> wrote:
Hi,
when thread1 wants to listen for some event from thread2, it executes wait().
when thread2 wants to inform about the event to thread1, it executes notify().
__TEXT_EDITED__
In my application :
thread1 first executes wait().
then thread2 executes notify().
But, The problem I am facing is :
notify() completes its execution even before thread1 actually starts waiting for the event and notify() is goes in vain and then thread1 keeps on waiting infinitely.
Regards,
Girish
You need state external to the event. A variable like
static int things_to_do = 0; // shared
void thread1()
{
scoped_lock lock(mutex);
while (!exit)
{
while (!things_to_do)
cond.wait(mutex);
do_things();
}
}
void thread2()
{
{
scoped_lock lock(mutex);
add_thing_to_do();
things_to_do++;
}
cond.notify();
}
Tony
-----Inline Attachment Follows-----
_______________________________________________
Boost-users mailing list
Boost-users_at_[hidden]
http://lists.boost.org/mailman/listinfo.cgi/boost-users
Boost-users list run by williamkempf at hotmail.com, kalb at libertysoft.com, bjorn.karlsson at readsoft.com, gregod at cs.rpi.edu, wekempf at cox.net