Opened 9 years ago
Closed 9 years ago
#9618 closed Bugs (fixed)
try_join_for problem: program is not terminate.
Reported by: | Owned by: | viboes | |
---|---|---|---|
Milestone: | Boost 1.56.0 | Component: | thread |
Version: | Boost 1.55.0 | Severity: | Problem |
Keywords: | try_join_for | Cc: |
Description
In the following,
auto pDummyThread = []{ // not important }; boost::thread t1( pDummyThread ); while( true ) { if ( t1.try_join_for(boost::chrono::milliseconds(0))/*(1)*/ ) break; }
If (1) is "try_join_for(boost::chrono::millseconds(1))", program will terminate.
But (1) is "try_join_for(boost::chrono::milliseconds(0))", program is not terminate.
I think that this program must terminate.
(boost 1.55.0, windows 8.1 64 bits, Visual Studio 2012)
Change History (15)
comment:1 by , 9 years ago
Owner: | changed from | to
---|---|
Status: | new → assigned |
comment:2 by , 9 years ago
comment:3 by , 9 years ago
I think that the thread of execution has completed even if the duration time is 0, so the function must return true.
follow-up: 5 comment:4 by , 9 years ago
HI, next follows an extract of the description I found in http://pubs.opengroup.org/onlinepubs/009695399/functions/pthread_cond_wait.html.
"The pthread_cond_timedwait() function shall be equivalent to pthread_cond_wait(), except that an error is returned if the absolute time specified by abstime passes (that is, system time equals or exceeds abstime) before the condition cond is signaled or broadcasted, or if the absolute time specified by abstime has already been passed at the time of the call."
I don't know how to implement what you are requesting.
Why do you want to wait for 0 milliseconds?
comment:5 by , 9 years ago
Replying to viboes:
2 reasons.
- Computer dependent value
Currently, a millisecond is enough time for "try_join_for" at my computer. But in the future, a millisecond may not be enough time for more faster computer. Therefore, current specification causes instability. The duration time must be computer independent value and it will be specified 0.
- Unnecessary redundant work
Every "try_join_for" call consumes time. It is a possibility that some case may not tolerant the redundant time.
follow-up: 7 comment:6 by , 9 years ago
What you are looking for id try_join() and this doesn't exists and don't know how to implement it.
You can also use nanoseconds(1) or attoseconds=duration<intmax_t, atto>.
comment:7 by , 9 years ago
Replying to viboes:
I'm sorry. I'm wrong.
Could you make "try_join()" function by using (something like) "try_join_for(chrono::nanoseconds(1))"?
I think that it is only (something like) syntax sugar.
But I become very happy if I get the function.
(And if could, could you teach me some url or something why "chrono::milliseconds(0)" is wrong and impossible? I'm sorry for my ignorance.. )
Thank you for reading.
comment:8 by , 9 years ago
A kind person teach me about #8323.
My understandings are as follows.
- Before boost 1.54, "try_join_for(chorno::milliseconds(0))" is NG in some multicore machine because timer sometimes is not monotonic. (My machine was luckily OK..)
- To avoid this problem, the duration time 0 must be avoid.
(3. Therefore my program behaviour became strange after installing boost 1.55).
I hope that something like "argument rel_time cannot be 0" will be written in document explicity for the person who is not good at English like me.
I'm sorry for taking your time.
Thank you very much.
comment:9 by , 9 years ago
I found that my program sometimes hang up even if "try_join_for(chrono::milliseconds(1))" uses in my environment...
I found that rel_time sometimes become -1.... in my windows 8.1 64 bits environment.
I modified the program.
boost/thread/detail/thread.hpp
bool try_join_until(const chrono::time_point<chrono::system_clock, chrono::nanoseconds>& tp) { chrono::milliseconds rel_time= chrono::ceil<chrono::milliseconds>(tp-chrono::system_clock::now()); return do_try_join_until(rel_time.count()); }
replace with
bool try_join_until(const chrono::time_point<chrono::system_clock, chrono::nanoseconds>& tp) { chrono::milliseconds rel_time= chrono::ceil<chrono::milliseconds>(tp-chrono::system_clock::now()); if ( rel_time < chrono::milliseconds::zero()) // rel_time must not be minus. rel_time= chrono::milliseconds::zero(); return do_try_join_until(rel_time.count()); }
I am not confident that this is OK because I don't have exact (academic) knowledge about thread.
Is this modification OK?
comment:10 by , 9 years ago
I have not a windows machine at hand. Please could you try this patch
git diff include/boost/thread/detail/thread.hpp diff --git a/include/boost/thread/detail/thread.hpp b/include/boost/thread/detail/thread.hpp index 5053b8d..64804f9 100644 --- a/include/boost/thread/detail/thread.hpp +++ b/include/boost/thread/detail/thread.hpp @@ -464,11 +464,20 @@ namespace boost inline void join(); #ifdef BOOST_THREAD_USES_CHRONO +#if defined(BOOST_THREAD_PLATFORM_WIN32) + template <class Rep, class Period> + bool try_join_for(const chrono::duration<Rep, Period>& rel_time) + { + chrono::milliseconds rel_time2= chrono::ceil<chrono::milliseconds>(rel_time); + return do_try_join_until(rel_time2.count()); + } +#else template <class Rep, class Period> bool try_join_for(const chrono::duration<Rep, Period>& rel_time) { return try_join_until(chrono::steady_clock::now() + rel_time); } +#endif template <class Clock, class Duration> bool try_join_until(const chrono::time_point<Clock, Duration>& t) {
comment:12 by , 9 years ago
Milestone: | To Be Determined → Boost 1.56.0 |
---|
comment:14 by , 9 years ago
comment:15 by , 9 years ago
Resolution: | → fixed |
---|---|
Status: | assigned → closed |
will return always false, as the duration time is already elapsed.
Why do you think that it could return true?