Как исправить проблему со сном високосной секунды без перезагрузки

Как исправить проблему со сном високосной секунды без перезагрузки

Я обнаружил, что после последней вставки секунды координации (2016-12-31 23:59:60) наше приложение CentOS7, в котором рабочие потоки спят в течение 1 секунды между заданиями, начало будить спящие потоки немедленно, а не через секунду. В целом, все спящие потоки пробуждаются на 1 секунду раньше ожидаемого времени пробуждения.

Самое простое и рабочее решение — перезагрузить бокс. Но в нашем случае это нежелательно. Есть ли способ исправить это без перезагрузки?

P.S. Для справки, вот простая программа на C++, которая воспроизводит проблему.

#include <boost/date_time.hpp>
#include <boost/thread.hpp>
#include <iostream>

using namespace std;


// this has to be run in a thread to be able to detect the issue
void check_thread()
{
    size_t expected_delay = 1000;
    cout << "Expected delay: " << expected_delay << " ms" << endl;
    boost::posix_time::ptime t1 = boost::posix_time::microsec_clock::universal_time();
    boost::this_thread::sleep(boost::posix_time::milliseconds(1000));
    boost::posix_time::ptime t2 = boost::posix_time::microsec_clock::universal_time();
    size_t actual_delay = (t2 - t1).total_milliseconds();
    cout << "Actual delay: " << actual_delay << " ms" << endl;
    if (abs(expected_delay - actual_delay) > 900) {
        cout << "Too big delay difference: " << (expected_delay - actual_delay) << endl;
        cout << "Possible leap second issue" << endl;
    }
    else {
        cout << "No issues found" << endl;
    }
}

int main()
{
    boost::thread_group g;
    g.create_thread(check_thread);
    g.join_all();
    return 0;
}

Здание:

g++ sleep_test.cpp -Wl,-Bstatic -lboost_thread -lboost_system -lboost_date_time -Wl,-Bdynamic -rdynamic -pthread

решение1

Синхронизировано ли ваше системное время с ntpdили ptp? Если нет, обновите свой tzdataпакет.

Для систем, не синхронизированных ntpd или ptp, требуется обновленный пакет tzdata, содержащий секунду координации 31 декабря. Обновленный пакет tzdata был выпущен как часть RHEA-2016-1982, и любые системы, использующие RHEL 7, которые не синхронизированы ntpd или ptp, должны обновиться до tzdata-2016g-2.el7 или более поздней версии, чтобы получить это исправление.

Устранение проблем с секундами в Red Hat Enterprise Linux

решение2

В дополнение к тому, что сказал Трой, в системах RHEL7, в которых tzdata не были обновлены к моменту применения дополнительной секунды и не запущен ntpd, требуется дополнительный шаг — вручную установить время на 1 секунду вперед, а затем вернуть его обратно:

date -s "+1 sec"
date -s "-1 sec"

Связанный контент