最新のうるう秒の挿入(2016-12-31 23:59:60)の後、ジョブ間でワーカースレッドが1秒間スリープしているCentOS7アプリケーションが、スリープしているスレッドを1秒ではなくすぐにウェイクアップし始めたことがわかりました。一般に、すべての睡眠は、予想される起床時間の1秒前に起床します。
最も簡単で実用的な解決策は、ボックスを再起動することです。しかし、私たちの場合、それは望ましくありません。再起動せずにこれを修正する方法はありますか?
PS。参考までに、問題を再現する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
トロイが言ったことに加えて、うるう秒が適用されるまでにtzdataを更新しておらず、ntpdを実行していないRHEL7システムでは、追加の手順が必要です。手動で時間を1秒進めてから、元に戻します。
date -s "+1 sec"
date -s "-1 sec"
システム時刻はntpd
またはptp
と同期していますか?そうでない場合は、tzdata
パッケージを更新してください。
Ntpdまたはptpによって同期されていないシステムの場合、12月31日のうるう秒を含む更新されたtzdataパッケージが必要です。更新されたtzdataパッケージはRHEA-2016-1982の一部としてリリースされ、ntpdまたはptpによって同期されていないRHEL 7を使用するシステムは、この修正を受け取るためにtzdata-2016g-2.el7以降のバージョンに更新する必要があります。