如何在不重启的情况下解决闰秒睡眠问题

amo*_*osk 5 linux leapsecond

我发现在最新的闰秒插入(2016-12-31 23:59:60)之后,我们的 CentOS7 应用程序的工作线程在作业之间休眠 1 秒,开始立即唤醒休眠线程,而不是在一秒钟内。一般来说,所有睡眠都比预期的唤醒时间提前 1 秒醒来。

最简单有效的解决方案是重新启动盒子。但这在我们的案例中是不可取的。有没有办法在不重新启动的情况下解决这个问题?

附注。作为参考,这里有一个简单的 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;
}
Run Code Online (Sandbox Code Playgroud)

建筑:

g++ sleep_test.cpp -Wl,-Bstatic -lboost_thread -lboost_system -lboost_date_time -Wl,-Bdynamic -rdynamic -pthread
Run Code Online (Sandbox Code Playgroud)

小智 6

您的系统时间是否与ntpd或同步ptp?如果没有,请更新您的tzdata软件包。

对于 ntpd 或 ptp 未同步的系统,需要包含 12 月 31 日闰秒的更新 tzdata 包。更新后的 tzdata 包是作为 RHEA-2016-1982 的一部分发布的,任何使用 RHEL 7 且未通过 ntpd 或 ptp 同步的系统都应更新到 tzdata-2016g-2.el7 或更高版本,以接收此修复程序。

解决红帽企业 Linux 中的闰秒问题


amo*_*osk 0

除了 Troy 所说的之外,在应用闰秒时尚未更新 tzdata 并且未运行 ntpd 的 RHEL7 系统上,需要一个额外的步骤 - 手动将时间向前设置 1 秒,然后将其恢复:

date -s "+1 sec"
date -s "-1 sec"
Run Code Online (Sandbox Code Playgroud)