Вот некоторый код C ++, иллюстрирующий мою проблему с минимальным примером:
// 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";
}
}
Пока я не включаю поддержку наносекунды, все работает как положено, но как только я раскомментирую #define, необходимый для поддержки наносекунды в boost :: posix_time, программа больше не преодолеет оператор if, так же, как если бы я вызвал join () вместо timed_join ().
Теперь я уже понял, что это происходит, потому что BOOST_DATE_TIME_POSIX_TIME_STD_CONFIG изменяет фактическое представление данных временных меток с одного 64-битного целого на 64 + 32-битное. Внутри заголовков полностью реализовано большое ускорение, но методы потоков — нет, и поэтому они не могут адаптироваться к новому формату данных, не компилируя их снова с соответствующими параметрами. Поскольку код предназначен для запуска на внешнем сервере, компиляция моей собственной версии boost не возможна и не отключает поддержку наносекунд.
Поэтому мой вопрос заключается в следующем: есть ли способ передать значение (порядка секунд) в timed_join () без использования несовместимых 96-битных методов posix_time и без изменения стандартных пакетов наддува?
Я работаю на Ubuntu 12.04 с надстройкой 1.46.1.
К сожалению, я не думаю, что ваша проблема может быть чисто решена, как написано. Поскольку библиотека, с которой вы ссылаетесь, была скомпилирована без поддержки наносекунды, по определению вы нарушаете правило одного определения, если вам случается включить поддержку наносекунды для любой части, которая уже скомпилирована в двоичный файл библиотеки. В этом случае вы включаете его через вызовы функций timed_join
,
Очевидное решение состоит в том, чтобы решить, от чего менее болезненно отказаться: создать собственный импульс или убрать наносекунды.
Менее очевидный «взлом», который может или не может полностью работать, это написать свой собственный timed_join
обертка, которая принимает объект потока и int
представляющих секунды или мс или что-то еще. Затем эта функция реализуется в исходном файле, где нет ничего другого, и это не разрешает наносекундные интервалы для конкретной цели вызова в скомпилированный бинарный буст. Еще раз хочу подчеркнуть, что если в какой-то момент вам не удастся полностью отделить такое использование, вы нарушите одно правило определения и столкнетесь с неопределенным поведением.
Других решений пока нет …