Boost ptime under MinGW not thread safe - c++

I have a problem with boost library. I'm using MinGW with gcc 4.5.2 to compile the following code:
unsigned long GetEpochSeconds()
{
using namespace boost::posix_time;
using namespace boost::gregorian;
ptime now(second_clock::universal_time());
ptime epoch(date(1970,1,1));
time_duration diff = now-epoch;
return diff.total_seconds();
}
The problem is that this code is not thread-safe. When I run it from within multiple threads, my application crashes. For now I've converted to c-standard functions like time, mktime etc. and everything works fine, but in the future I will need a few boost time functions.
I was compiling also with -D_REENTRANT, but this didn't help.
Thanks for any suggestions.

Check whether your code is calling gmtime() or gmtime_r() (use a debugger for this). See http://www.boost.org/doc/libs/1_48_0/boost/date_time/c_time.hpp and note that BOOST_DATE_TIME_HAS_REENTRANT_STD_FUNCTIONS must be defined in order for getting the time to be thread-safe.

Related

C++ program to get the current time

I have to create a simple window service program which is to be executed in visual studio using C++ language. I have used ctime and localtime keywords but it returns an error saying:
This function or variable may be unsafe. Consider using any other ....
I am using Visual Studio 2019
You can use std::chrono::system_clock::now() function to get the current time point.
ctime and localtime are unsafe as these returns pointer to static data.
Therefore, ctime_s and localtime_s are provided in VS2019 (also in some earlier versions), which takes a pre allocated pointer in which value need to be returned and hence safe to use.

Boost date/time microsec_clock not compiling correctly

I'm trying to use the date/time facilities of the C++ Boost library v1.41. (Note: this is Linux, not Windows; g++ v4.4.7)
Code:
#include <boost/date_time/posix_time/posix_time.hpp>
using boost::posix_time::ptime;
using boost::date_time::microsec_clock;
:
t1 = (boost::date_time::microsec_clock::local_time()); // line 208
The error:
tom.cpp:208: error: 'template<class time_type> class boost::date_time::microsec_clock' used without template parameters
Now, there's this in boost/date_time/posix_time/posix_time_types.hpp:
#ifdef BOOST_DATE_TIME_HAS_HIGH_PRECISION_CLOCK
//! A time clock that has a resolution of one microsecond
/*! \ingroup time_basics
*/
typedef date_time::microsec_clock<ptime> microsec_clock;
#endif
What I'm concluding is that BOOST_DATE_TIME_HAS_HIGH_PRECISION_CLOCK is undefined, resulting in the typedef never happening, resulting in the reference to "microsec_clock" looking like it needed a template parameter.
As far as I can tell, I'm following the Boost date_time documentation to the letter. Any ideas?
I have the same problem right now.
Yesterday it worked without any problems but today I needed to delete all my compiled libraries and recompile them due to a svn corruption problem. Ever since this error occurred.
The way to fix it is rather simple.
Just use
t1 = (boost::posix_time::microsec_clock::local_time());
instead of
t1 = (boost::date_time::microsec_clock::local_time());
This will preset the time type to posix format however it will not fix the initial problem with BOOST_DATE_TIME_HAS_HIGH_PRECISION_CLOCK.
I hope this was of help to you.

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.

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.

boost::this_thread::sleep() vs. nanosleep()?

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.