The problem is in the implementation of std::this_thread:sleep_until(..) which calls sleep_for(..), which calls nanosleep().
(See the gnu sources, line 271.)
See the following Stackoverflow questions:
You don't appear to need the high resolution of nanosleep(). You might write your own solution with a permissive open source license, and call sleep() instead of nanosleep().
If you do need sub-second resolution, I recommend the technique of calling select() rather than nanosleep(). select() is designed to block very efficiently for sub-second delays, and the timeout parameter is respected accurately enough by most operating systems that it is useful for sub-second timing while yielding the CPU.
You can even create a socket for the purpose of passing to select(), in theerror_fds parameter, where the socket can be used as a cross-thread "signal" when it is passed to close() and becomes an "error" state socket.