[Boost-bugs] [Boost C++ Libraries] #11331: boost::this_thread::sleep_for does not sleep for requested time

Subject: [Boost-bugs] [Boost C++ Libraries] #11331: boost::this_thread::sleep_for does not sleep for requested time
From: Boost C++ Libraries (noreply_at_[hidden])
Date: 2015-05-21 23:01:15


#11331: boost::this_thread::sleep_for does not sleep for requested time
-----------------------------------------+----------------------
 Reporter: Scott Minor <scott.minor@…> | Owner: anthonyw
     Type: Bugs | Status: new
Milestone: To Be Determined | Component: thread
  Version: Boost 1.58.0 | Severity: Problem
 Keywords: sleep_for |
-----------------------------------------+----------------------
 boost::this_thread::sleep_for does not accurately sleep for the requested
 amount of time (+/- 30ms) on a Windows 7 x64 environment when the
 requested time is on the order of half a minute.
 std::this_thread::sleep_for is able to accurately sleep for the requested
 amount of time. Here is a sample program illustrating the issue:


 {{{
 #include <boost/thread.hpp>
 #include <boost/chrono.hpp>

 #include <chrono>
 #include <iostream>
 #include <thread>

 void boostThreadFunction ()
 {
    std::cout << "Starting Boost thread" << std::endl;
    for (int i = 0; i < 10; ++i)
    {
       auto sleep_time = boost::chrono::milliseconds {29000 + 100 * i};
       auto mark = std::chrono::steady_clock::now ();
       boost::this_thread::sleep_for (sleep_time);
       auto duration =
 std::chrono::duration_cast<std::chrono::milliseconds>(
          std::chrono::steady_clock::now () - mark);
       std::cout << "Boost thread:" << std::endl;
       std::cout << "\tSupposed to sleep for:\t" << sleep_time.count () <<
 " ms" << std::endl;
       std::cout << "\tActually slept for:\t" << duration.count () << " ms"
 << std::endl << std::endl;
    }
 }

 void stdThreadFunction ()
 {
    std::cout << "Starting Std thread" << std::endl;
    for (int i = 0; i < 10; ++i)
    {
       auto sleep_time = std::chrono::milliseconds {29000 + 100 * i};
       auto mark = std::chrono::steady_clock::now ();
       std::this_thread::sleep_for (sleep_time);
       auto duration =
 std::chrono::duration_cast<std::chrono::milliseconds>(
          std::chrono::steady_clock::now () - mark);
       std::cout << "Std thread:" << std::endl;
       std::cout << "\tSupposed to sleep for:\t" << sleep_time.count () <<
 " ms" << std::endl;
       std::cout << "\tActually slept for:\t" << duration.count () << " ms"
 << std::endl << std::endl;
    }
 }

 int main ()
 {
    boost::thread boost_thread (&boostThreadFunction);
    std::this_thread::sleep_for (std::chrono::seconds (10));
    std::thread std_thread (&stdThreadFunction);
    boost_thread.join ();
    std_thread.join ();
    system ("pause");
    return 0;
 }
 }}}

 Here is the output produced in my environment:


 {{{
 Starting Boost thread
 Starting Std thread
 Boost thread:
         Supposed to sleep for: 29000 ms
         Actually slept for: 29690 ms

 Std thread:
         Supposed to sleep for: 29000 ms
         Actually slept for: 29009 ms

 Boost thread:
         Supposed to sleep for: 29100 ms
         Actually slept for: 29999 ms

 Std thread:
         Supposed to sleep for: 29100 ms
         Actually slept for: 29111 ms

 Boost thread:
         Supposed to sleep for: 29200 ms
         Actually slept for: 29990 ms

 Std thread:
         Supposed to sleep for: 29200 ms
         Actually slept for: 29172 ms

 Boost thread:
         Supposed to sleep for: 29300 ms
         Actually slept for: 30005 ms

 Std thread:
         Supposed to sleep for: 29300 ms
         Actually slept for: 29339 ms

 Boost thread:
         Supposed to sleep for: 29400 ms
         Actually slept for: 30003 ms

 Std thread:
         Supposed to sleep for: 29400 ms
         Actually slept for: 29405 ms

 Boost thread:
         Supposed to sleep for: 29500 ms
         Actually slept for: 29999 ms

 Std thread:
         Supposed to sleep for: 29500 ms
         Actually slept for: 29472 ms

 Boost thread:
         Supposed to sleep for: 29600 ms
         Actually slept for: 29999 ms

 Std thread:
         Supposed to sleep for: 29600 ms
         Actually slept for: 29645 ms

 Boost thread:
         Supposed to sleep for: 29700 ms
         Actually slept for: 29998 ms

 Std thread:
         Supposed to sleep for: 29700 ms
         Actually slept for: 29706 ms

 Boost thread:
         Supposed to sleep for: 29800 ms
         Actually slept for: 29998 ms

 Std thread:
         Supposed to sleep for: 29800 ms
         Actually slept for: 29807 ms

 Boost thread:
         Supposed to sleep for: 29900 ms
         Actually slept for: 30014 ms

 Std thread:
         Supposed to sleep for: 29900 ms
         Actually slept for: 29915 ms

 }}}

 Looking at libs/thread/src/win32/thread.cpp, this inaccuracy may be by
 design; a +/-5% tolerance appears to be added to the wait time to take
 advantage of coalescing timers. See related StackOverflow question:
 http://stackoverflow.com/questions/30381866/boost-thread-wakes-up-too-
 late-in-1-58

 However, we are dependent on sleep_for() being as accurate as possible;
 for us, this is a breaking change.

-- 
Ticket URL: <https://svn.boost.org/trac/boost/ticket/11331>
Boost C++ Libraries <http://www.boost.org/>
Boost provides free peer-reviewed portable C++ source libraries.

This archive was generated by hypermail 2.1.7 : 2017-02-16 18:50:18 UTC