[Boost-Threads] Assertion during a second call to thread::join()
Hi,
Does anyone know the reason for the behavior in the following example
program?
This example attempts to simulate the scenario where two threads wait on
a third thread. However, I realize that the following is actually one
thread waiting on a second thread twice.
Regards,
Jason
My Environment: MSVC 8.0, boost v1.33.1
#include
Aubrey, Jason wrote:
Hi,
Does anyone know the reason for the behavior in the following example program?
This example attempts to simulate the scenario where two threads wait on a third thread. However, I realize that the following is actually one thread waiting on a second thread twice.
Regards, Jason
My Environment: MSVC 8.0, boost v1.33.1
#include
#include void f() { }
void main() { boost::thread t(f); t.join(); t.join(); // Causes an assertion
A call to thread::join() requires the thread to be joinable. After the first call to join() the thread has finished and is not joinable anymore. If you'd like to execute f twice, create a seperate thread for each run. hth Sascha
I think what you need is a condition variable and not join. You can use notify_one and notify_all member of a common condition variable to wake up one or respective all waiting threads: http://www.boost.org/doc/html/condition.html Please read this article in DDJ about boost threads there is written how to handle different threading issues: http://www.ddj.com/dept/cpp/184401518 With Kind Regards, Ovanes Markarian On Thu, August 24, 2006 09:05, Sascha Seewald wrote:
Aubrey, Jason wrote:
Hi,
Does anyone know the reason for the behavior in the following example program?
This example attempts to simulate the scenario where two threads wait on a third thread. However, I realize that the following is actually one thread waiting on a second thread twice.
Regards, Jason
My Environment: MSVC 8.0, boost v1.33.1
#include
#include void f() { }
void main() { boost::thread t(f); t.join(); t.join(); // Causes an assertion
A call to thread::join() requires the thread to be joinable. After the first call to join() the thread has finished and is not joinable anymore. If you'd like to execute f twice, create a seperate thread for each run.
hth
Sascha
_______________________________________________ Boost-users mailing list Boost-users@lists.boost.org http://lists.boost.org/mailman/listinfo.cgi/boost-users
I can accept that I should use a condition variable for this situation but I'm still not understanding the reason why. If the intent of join is to block until the thread has completed, why doesn't it just return when it realizes the thread has completed? Also how is the second call any different from the first call occurring after the thread has completed? Apparently the C# designers had my same perspective since the following completes without error: // C# sample program to demonstrate join() semantics using System.Threading; namespace Test1 { class Sample { void f(){} static void Main(string[] args) { Sample s = new Sample(); Thread t = new Thread(new ThreadStart(s.f)); t.Start(); t.Join(); t.Join(); // No exception is thrown here, call simply returns } } } Regards, Jason -----Original Message----- From: boost-users-bounces@lists.boost.org [mailto:boost-users-bounces@lists.boost.org] On Behalf Of Ovanes Markarian Sent: Thursday, August 24, 2006 4:25 AM To: boost-users@lists.boost.org Subject: Re: [Boost-users] [Boost-Threads] Assertion during a second call to thread::join() I think what you need is a condition variable and not join. You can use notify_one and notify_all member of a common condition variable to wake up one or respective all waiting threads: http://www.boost.org/doc/html/condition.html Please read this article in DDJ about boost threads there is written how to handle different threading issues: http://www.ddj.com/dept/cpp/184401518 With Kind Regards, Ovanes Markarian On Thu, August 24, 2006 09:05, Sascha Seewald wrote:
Aubrey, Jason wrote:
Hi,
Does anyone know the reason for the behavior in the following example
program?
This example attempts to simulate the scenario where two threads wait
on a third thread. However, I realize that the following is actually
one thread waiting on a second thread twice.
Regards, Jason
My Environment: MSVC 8.0, boost v1.33.1
#include
#include void f() { }
void main() { boost::thread t(f); t.join(); t.join(); // Causes an assertion
A call to thread::join() requires the thread to be joinable. After the
first call to join() the thread has finished and is not joinable anymore. If you'd like to execute f twice, create a seperate thread for each run.
hth
Sascha
_______________________________________________ Boost-users mailing list Boost-users@lists.boost.org http://lists.boost.org/mailman/listinfo.cgi/boost-users
_______________________________________________ Boost-users mailing list Boost-users@lists.boost.org http://lists.boost.org/mailman/listinfo.cgi/boost-users
There are many things which boost::threads do not have (event variables, some mutex types leading to deadlocks were removed). As I read in the docs, the main idea was to design _robust_ threads. Performance also plays a huge role. If you look into the implementation of thread::join you will see that there is no mutex defined. So it is not safe to access join() from multiple threads, since one thread could wait on object which was finished anyway: void thread::join() { assert(m_joinable); //See race condition comment below int res = 0; #if defined(BOOST_HAS_WINTHREADS) res = WaitForSingleObject(reinterpret_cast<HANDLE>(m_thread), INFINITE); assert(res == WAIT_OBJECT_0); res = CloseHandle(reinterpret_cast<HANDLE>(m_thread)); assert(res); #elif defined(BOOST_HAS_PTHREADS) res = pthread_join(m_thread, 0); assert(res == 0); #elif defined(BOOST_HAS_MPTASKS) OSStatus lStatus = threads::mac::detail::safe_wait_on_queue( m_pJoinQueueID, NULL, NULL, NULL, kDurationForever); assert(lStatus == noErr); #endif // This isn't a race condition since any race that could occur would // have us in undefined behavior territory any way. m_joinable = false; } With Kind Regards, Ovanes Markarian On Thu, August 24, 2006 16:03, Aubrey, Jason wrote:
I can accept that I should use a condition variable for this situation but I'm still not understanding the reason why.
If the intent of join is to block until the thread has completed, why doesn't it just return when it realizes the thread has completed? Also how is the second call any different from the first call occurring after the thread has completed?
Apparently the C# designers had my same perspective since the following completes without error:
// C# sample program to demonstrate join() semantics using System.Threading; namespace Test1 { class Sample { void f(){} static void Main(string[] args) { Sample s = new Sample(); Thread t = new Thread(new ThreadStart(s.f)); t.Start(); t.Join(); t.Join(); // No exception is thrown here, call simply returns } } }
Regards, Jason
-----Original Message----- From: boost-users-bounces@lists.boost.org [mailto:boost-users-bounces@lists.boost.org] On Behalf Of Ovanes Markarian Sent: Thursday, August 24, 2006 4:25 AM To: boost-users@lists.boost.org Subject: Re: [Boost-users] [Boost-Threads] Assertion during a second call to thread::join()
I think what you need is a condition variable and not join. You can use notify_one and notify_all member of a common condition variable to wake up one or respective all waiting threads:
http://www.boost.org/doc/html/condition.html
Please read this article in DDJ about boost threads there is written how to handle different threading issues: http://www.ddj.com/dept/cpp/184401518
With Kind Regards,
Ovanes Markarian
On Thu, August 24, 2006 09:05, Sascha Seewald wrote:
Aubrey, Jason wrote:
Hi,
Does anyone know the reason for the behavior in the following example
program?
This example attempts to simulate the scenario where two threads wait
on a third thread. However, I realize that the following is actually
one thread waiting on a second thread twice.
Regards, Jason
My Environment: MSVC 8.0, boost v1.33.1
#include
#include void f() { }
void main() { boost::thread t(f); t.join(); t.join(); // Causes an assertion
A call to thread::join() requires the thread to be joinable. After the
first call to join() the thread has finished and is not joinable anymore. If you'd like to execute f twice, create a seperate thread for each run.
hth
Sascha
_______________________________________________ Boost-users mailing list Boost-users@lists.boost.org http://lists.boost.org/mailman/listinfo.cgi/boost-users
_______________________________________________ Boost-users mailing list Boost-users@lists.boost.org http://lists.boost.org/mailman/listinfo.cgi/boost-users _______________________________________________ Boost-users mailing list Boost-users@lists.boost.org http://lists.boost.org/mailman/listinfo.cgi/boost-users
participants (3)
-
Aubrey, Jason
-
Ovanes Markarian
-
Sascha Seewald