Ускорение проблемы времени високосных секунд - PullRequest
4 голосов
/ 07 мая 2010

Я использую timed_wait из библиотеки boost C ++, и у меня возникает проблема с високосными секундами.

Вот быстрый тест:

#include <boost/thread.hpp>
#include <stdio.h>
#include <boost/date_time/posix_time/posix_time.hpp>

int main(){
        // Determine the absolute time for this timer.
        boost::system_time tAbsoluteTime = boost::get_system_time() + boost::posix_time::milliseconds(35000);

        bool done;
        boost::mutex m;
        boost::condition_variable cond;

        boost::unique_lock<boost::mutex> lk(m);
        while(!done)
        {
            if(!cond.timed_wait(lk,tAbsoluteTime))
            {
                done = true;
                std::cout << "timed out";
            }
        }
        return 1;
}

Функция timed_wait возвращает 24 секундыраньше, чем следовало24 секунды - это текущее количество високосных секунд в UTC.

Итак, повышение широко используется, но я не смог найти информацию об этой конкретной проблеме.Кто-нибудь еще испытывал эту проблему?Каковы возможные причины и решения?

Примечания: Я использую boost 1.38 в системе Linux.Я слышал, что эта проблема не возникает в MacOS.

ОБНОВЛЕНИЕ: Немного больше информации: это происходит на 2-х redhat машинах с ядром 2.6.9.Я выполнил тот же код на машине с Ubuntu с ядром 2.6.30, и таймер ведет себя так, как и ожидалось.

Итак, я думаю, что это, вероятно, вызвано операционной системой или неправильной настройкойна машинах Redhat.

Я кодировал обходной путь, который корректирует время по UTC, а затем получает разницу от этой настройки и добавляет к исходному времени.Это выглядит как плохая идея для меня, потому что, если этот код выполняется на машине без этой проблемы, это может быть 24 секунды ВПЕРЕД.Все еще не смог найти причину этого.

Ответы [ 3 ]

2 голосов
/ 07 мая 2010

В системе Linux системные часы будут соответствовать стандарту POSIX, который обязывает високосные секунды НЕ наблюдаются! Если вы ожидали иного, это, вероятно, источник несоответствия, которое вы видите. Этот документ содержит отличное объяснение того, как UTC относится к другим временным шкалам, и к проблемам, с которыми можно столкнуться, если полагаться на концепцию хронометража операционной системы.

1 голос
/ 07 мая 2010

Возможно ли, что готово устанавливается преждевременно, и ложное пробуждение приводит к тому, что цикл завершается раньше, чем вы ожидали?

0 голосов
/ 10 мая 2010

Хорошо, вот что я сделал.Это обходной путь, и я не доволен им, но это было лучшее, что я мог придумать:

int main(){
        typedef boost::date_time::c_local_adjustor<boost::system_time> local_adj;

        // Determine the absolute time for this timer.
        boost::system_time tAbsoluteTime = boost::get_system_time() + boost::posix_time::milliseconds(25000);

        /*
         * A leap second is a positive or negative one-second adjustment to the Coordinated
         * Universal Time (UTC) time scale that keeps it close to mean solar time.
         * UTC, which is used as the basis for official time-of-day radio broadcasts for civil time,
         * is maintained using extremely precise atomic clocks. To keep the UTC time scale close to
         * mean solar time, UTC is occasionally corrected by an adjustment, or "leap",
         * of one second.
         */
        boost::system_time tAbsoluteTimeUtc = local_adj::utc_to_local(tAbsoluteTime);

        // Calculate the local-to-utc difference.
        boost::posix_time::time_duration tLocalUtcDiff = tAbsoluteTime - tAbsoluteTimeUtc;

        // Get only the seconds from the difference. These are the leap seconds.
        tAbsoluteTime += boost::posix_time::seconds(tLocalUtcDiff.seconds());

        bool done;
        boost::mutex m;
        boost::condition_variable cond;

        boost::unique_lock<boost::mutex> lk(m);
        while(!done)
        {
            if(!cond.timed_wait(lk,tAbsoluteTime))
            {
                done = true;
                std::cout << "timed out";
            }
        }
        return 1;
}

Я тестировал его на проблемных и не проблемных машинах, и он работал как ожидалось на обеихтак что я держу его до тех пор, пока не найду лучшего решения.

Спасибо всем за помощь.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...