Opened 9 years ago

Closed 9 years ago

#9618 closed Bugs (fixed)

try_join_for problem: program is not terminate.

Reported by: oniprog <tkuman@…> 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 viboes, 9 years ago

Owner: changed from Anthony Williams to viboes
Status: newassigned

comment:2 by viboes, 9 years ago

try_join_for(boost::chrono::milliseconds(0))

will return always false, as the duration time is already elapsed.

Why do you think that it could return true?

comment:3 by tkuman@…, 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.

comment:4 by viboes, 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?

in reply to:  4 comment:5 by tkuman@…, 9 years ago

Replying to viboes:

2 reasons.

  1. 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.

  1. Unnecessary redundant work

Every "try_join_for" call consumes time. It is a possibility that some case may not tolerant the redundant time.

comment:6 by viboes, 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>.

in reply to:  6 comment:7 by oniprog <tkuman@…>, 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 oniprog <tkuman@…>, 9 years ago

A kind person teach me about #8323.

My understandings are as follows.

  1. 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..)
  1. 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 oniprog <tkuman@…>, 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 viboes, 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:11 by tkuman@…, 9 years ago

I applied the patch. My program works fine!.

Thank you very much.

comment:12 by viboes, 9 years ago

Milestone: To Be DeterminedBoost 1.56.0

comment:13 by viboes, 9 years ago

See also #9654.

comment:15 by viboes, 9 years ago

Resolution: fixed
Status: assignedclosed
Note: See TracTickets for help on using tickets.