boost::this_thread::sleep() vs. nanosleep()? - c++

I recently came across the need to sleep the current thread for an exact period of time. I know of two methods of doing so on a POSIX platform: using nanosleep() or using boost::this_thread::sleep().
Out of curiosity more than anything else, I was wondering what the differences are between the two approaches. Is there any difference in precision, and is there any reason not to use the Boost approach?
nanosleep() approach:
#include <time.h>
...
struct timespec sleepTime;
struct timespec returnTime;
sleepTime.tv_sec = 0;
sleepTime.tv_nsec = 1000;
nanosleep(&sleepTime, &returnTime);
Boost approach:
#include <boost/date_time/posix_time/posix_time.hpp>
#include <boost/thread/thread.hpp>
...
boost::this_thread::sleep(boost::posix_time::nanoseconds(1000));

The few reasons why use boost that I can think of:
boost::this_thread::sleep() is an
interruption point in boost.thread
boost::this_thread::sleep() can be
drop-in replaced by C++0x's
std::this_thread::sleep_until() in
future
For why not -- if you're not using threads at all, or of everything else in your project uses POSIX calls, then nanosleep() makes more sense.
As for precision, on my system both boost and nanosleep() call the same system call, hrtimer_nanosleep(). I imagine boost authors try to get the highest precision possible on each system and for me it happens to be the same thing as what nanosleep() provides.

How about because your nanonsleep example is wrong.
#include <time.h>
...
struct timespec sleepTime;
struct timespec time_left_to_sleep;
sleepTime.tv_sec = 0;
sleepTime.tv_nsec = 1000;
while( (sleepTime.tv_sec + sleepTime.tv_nsec) > 0 )
{
nanosleep(&sleepTime, &time_left_to_sleep);
sleepTime.tv_sec = time_left_to_sleep.tv_sec;
sleepTime.tv_nsec = time_left_to_sleep.tv_nsec;
}
Admittedly if you're only sleeping for 1 microsecond waking up too early shouldn't be an issue, but in the general case this is the only way to get it done.
And just to ice the cake in boost's favor, boost::this_thread::sleep() is implemented using nanosleep(). They just took care of all the insane corner cases for you.

is there any reason not to use the Boost approach
I suppose this is kind of obvious, but the only reason I can think of is that you'd require boost to compile your project.

For me the main reason for using the boost variant is platform independence. If you are required to compile your application for both posix and Windows platforms, for example, the platform sleep is not sufficient.

Related

How to properly implement a cross-platform spinlock in c++

Essentially, my question is:
What does an "good" implementation of a spinlock look like in c++ which works on the "usual" CPU/OS/Compiler combinations (x86 & arm, Windows & Linux, msvc & clang & g++ (maybe also icc) ).
Explanation:
As I wrote in the answer to a different question, it is fairly easy to write a working spinlock in c++11. However, as pointed out (in the comments as well as in e.g. spinlock-vs-stdmutextry-lock), such an implementation comes with some performance problems in case of congestion, which imho can only be solved by using platform specific instructions (intrinsics / os primitives / assembly?).
I'm not looking for a super optimized version (I expect that would only make sense if you have very precise knowledge about the exact platform and workload and need every last bit of efficiency) but something that lives around the mythical 20/80 tradeoff point i.e. I want to avoid the most important pitfalls in most cases while still keeping the solution as simple and understandable as possible.
In general, I'd expect the result to look something like thist:
#include <atomic>
#ifdef _MSC_VER
#include <Windows.h>
#define YIELD_CPU YieldProcessor();
#elif defined(...)
#define YIELD_CPU ...
...
#endif
class SpinLock {
std::atomic_flag locked = ATOMIC_FLAG_INIT;
public:
void lock() {
while (locked.test_and_set(std::memory_order_acquire)) {
YIELD_CPU;
}
}
void unlock() {
locked.clear(std::memory_order_release);
}
};
But I don't know
if a YIELD_CPU macro inside the loop is all that's needed or if there are any other problematic aspects (e.g. can/should we indicate if we expect the test_and_set to succeed most of the time)
what the appropriate mapping for YIELD_CPU on the different CPU/OS/Compiler combinations is (and if possible I'd like to avoid dragging in a heavy weight header like Windows.h)
Note: I'm also interested in answers that only cover a subset of the mentioned platforms, but might not mark them as the accepted answer and/or merge them into a separate community answer.

How can I use boost::thread::timed_join with nanoseconds enabled in boost::date_time?

Here is some C++ code illustrating my problem with a minimal expample:
// uncomment the next line, to make it hang up:
//#define BOOST_DATE_TIME_POSIX_TIME_STD_CONFIG //needed for nanosecond support of boost
#include <boost/thread.hpp>
void foo()
{
while(true);
}
int main(int noParameters, char **parameterArray)
{
boost::thread MyThread(&foo);
if ( MyThread.timed_join( boost::posix_time::seconds(1) ) )
{
std::cout<<"\nDone!\n";
}
else
{
std::cerr<<"\nTimed out!\n";
}
}
As long as I don't turn on the nanosecond support everthing works as expected, but as soon as I uncomment the #define needed for the nanosecond support in boost::posix_time the program doesn't get past the if-statement any more, just as if I had called join() instead of timed_join().
Now I've already figured out, that this happens because BOOST_DATE_TIME_POSIX_TIME_STD_CONFIG changes the actual data representation of the timestamps from a single 64bit integer to 64+32 bit. A lot boost stuff is completely implemented inside the headers but the thread methods are not and because of that they cannot adapt to the new data format without compiling them again with the apropriate options. Since the code is meant to run on an external server, compiling my own version of boost is not an option and neither is turning off the nanosecond support.
Therefore my question is as follows: Is there a way to pass on a value (on the order of seconds) to timed_join() without using the incompatible 96bit posix_time methods and without modifying the standard boost packages?
I'm running on Ubuntu 12.04 with boost 1.46.1.
Unfortunately I don't think your problem can be cleanly solved as written. Since the library you're linking against was compiled without nanosecond support, by definition you violate the one-definition rule if you happen to enable nanosecond support for any piece that's already compiled into the library binary. In this case, you're enabling it across the function calls to timed_join.
The obvious solution is to decide which is less painful to give up: Building your own boost, or removing nanosecond times.
The less obvious "hack" that may or may not totally work is to write your own timed_join wrapper that takes a thread object and an int representing seconds or ms or whatever. Then this function is implemented in a source file with nothing else and that does not enable nanosecond times for the specific purpose of calling into the compiled boost binary. Again I want to stress that if at any point you fail to completely segregate such usages you'll violate the one definition rule and run into undefined behavior.

c++ threads - parallel processing

I was wondering how to execute two processes in a dual-core processor in c++.
I know threads (or multi-threading) is not a built-in feature of c++.
There is threading support in Qt, but I did not understand anything from their reference. :(
So, does anyone know a simple way for a beginner to do it. Cross-platform support (like Qt) would be very helpful since I am on Linux.
Try the Multithreading in C++0x part 1: Starting Threads as a 101. If you compiler does not have C++0x support, then stay with Boost.Thread
Take a look at Boost.Thread. This is cross-platform and a very good library to use in your C++ applications.
What specifically would you like to know?
The POSIX thread (pthreads) library is probably your best bet if you just need a simple threading library, it has implementations both on Windows and Linux.
A guide can be found e.g. here. A Win32 implementation of pthreads can be downloaded here.
Edit: Didn't see you were on Linux. In that case I'm not 100% sure but I think the libraries are probably already bundled in with your GCC installation.
I'd recommend using the Boost libraries Boost.Thread instead. This will wrap platform specifics of Win32 and Posix, and give you a solid set of threading and synchronization objects. It's also in very heavy use, so finding help on any issues you encounter on SO and other sites is easy.
You can search for a free PDF book "C++-GUI-Programming-with-Qt-4-1st-ed.zip" and read Chapter 18 about Multi-threading in Qt.
Concurrent programming features supported by Qt includes (not limited to) the following:
Mutex
Read Write Lock
Semaphore
Wait Condition
Thread Specific Storage
However, be aware of the following trade-offs with Qt:
Performance penalties vs native threading libraries. POSIX thread (pthreads) has been native to Linux since kernel 2.4 and may not substitute for < process.h > in W32API in all situations.
Inter-thread communication in Qt is implemented with SIGNAL and SLOT constructs. These are NOT part of the C++ language and are implemented as macros which requires proprietary code generators provided by Qt to be fully compiled.
If you can live with the above limitations, just follow these recipes for using QThread:
#include < QtCore >
Derive your own class from QThread. You must implement a public function run() that returns void to contain instructions to be executed.
Instantiate your own class and call start() to kick off a new thread.
Sameple Code:
#include <QtCore>
class MyThread : public QThread {
public:
void run() {
// do something
}
};
int main(int argc, char** argv) {
MyThread t1, t2;
t1.start(); // default implementation from QThread::start() is fine
t2.start(); // another thread
t1.wait(); // wait for thread to finish
t2.wait();
return 0;
}
As an important note in c++14, the use of concurrent threading is available:
#include<thread>
class Example
{
auto DoStuff() -> std::string
{
return "Doing Stuff";
}
auto DoStuff2() -> std::string
{
return "Doing Stuff 2";
}
};
int main()
{
Example EO;
std::string(Example::*func_pointer)();
func_pointer = &Example::DoStuff;
std::future<string> thread_one = std::async(std::launch::async, func_pointer, &EO); //Launching upon declaring
std::string(Example::*func_pointer_2)();
func_pointer_2 = &Example::DoStuff2;
std::future<string> thread_two = std::async(std::launch::deferred, func_pointer_2, &EO);
thread_two.get(); //Launching upon calling
}
Both std::async (std::launch::async, std::launch::deferred) and std::thread are fully compatible with Qt, and in some cases may be better at working in different OS environments.
For parallel processing, see this.

Where is msleep declared?

The source from here says that it is supposed to work on the iPhone. I have worked with it, but I get 2 errors, saying that msleep() is undeclared. I have tried to include unistd.h, time.h, and numerous others. How can I get this to work? Thanks.
The msleep() is a non-standard artifact from early BSDs, before the clock_nanosleep() and nanosleep() made it into POSIX.
It is unportable. On some systems it is available by default - on others one has to compile the code with _BSD_SOURCE define.
iPhone is a distant relative of Mac OS X, which is distant relative of NeXT, which is very distant relative of BSD 4.x. So the function might have stuck in some header/library somewhere, but you shouldn't use it anyway. If memory serves me right, check the NSThread's sleepForTimeInterval: static method.
There is nothing in that linked thread stating that msleep is available. The original author, bagusflyer, actually implemented their own msleep, stating:
Sorry. Maybe I missed something in my code. Here is my msleep:
#include <sys/time.h>
void msleep (unsigned int ms) {
int microsecs;
struct timeval tv;
microsecs = ms * 1000;
tv.tv_sec = microsecs / 1000000;
tv.tv_usec = microsecs % 1000000;
select (0, NULL, NULL, NULL, &tv);
}
However, you should be careful about using that code since I think, from memory, that select() is interruptable.
Maybe you can use usleep(). It is also in unistd.h.

How to sleep a C++ Boost Thread

Seems impossible to sleep a thread using boost::thread.
Method sleep requires a system_time but how can I build it?
Looking inside libraries doesn't really help much...
Basically I have a thread
inside the function that I pass to this thread as entry point, I would like to call something like
boost::this_thread::sleep
or something, how to do this?
Thank you
Depending on your version of Boost:
Either...
#include <boost/chrono.hpp>
#include <boost/thread/thread.hpp>
boost::this_thread::sleep_for(boost::chrono::milliseconds(100));
Or...
#include <boost/date_time/posix_time/posix_time.hpp>
#include <boost/thread/thread.hpp>
boost::this_thread::sleep(boost::posix_time::milliseconds(100));
You can also use microseconds, seconds, minutes, hours and maybe some others, I'm not sure.
From another post, I learned boost::this_thread::sleep is deprecated for Boost v1.5.3: http://www.boost.org/doc/libs/1_53_0/doc/html/thread/thread_management.html
Instead, try
void sleep_for(const chrono::duration<Rep, Period>& rel_time);
e.g.
boost::this_thread::sleep_for(boost::chrono::seconds(60));
Or maybe try
void sleep_until(const chrono::time_point<Clock, Duration>& abs_time);
I was using Boost v1.53 with the deprecated sleep function, and it aperiodically crashed the program. When I changed calls to the sleep function to calls to the sleep_for function, the program stopped crashing.
firstly
boost::posix_time::seconds secTime(1);
boost::this_thread::sleep(secTime);
secondly
boost::this_thread::sleep(boost::posix_time::milliseconds(100));
I learned the hard way that at least in MS Visual Studio (tried 2013 and 2015) there is the huge difference between
boost::this_thread::sleep(boost::posix_time::microseconds(SmallIterval));
and
boost::this_thread::sleep_for(boost::chrono::microseconds(SmallIterval));
or
std::this_thread::sleep_for(std::chrono::microseconds(SmallIterval));
when interval is smaller than some rather substantial threshold (I saw threshold of 15000 microseconds = 15 milliseconds).
If SmallIterval is small, sleep() does instantaneous interruption. sleep(100 mks) behaves as sleep(0 mks).
But sleep_for() for the time interval smaller than a threshold pauses for the entire threshold. sleep_for(100 mks) behaves as sleep_for(15000 mks).
Behavior for intervals larger than threshold and for value 0 is the same.