У меня есть приложение C ++, работающее на Raspberry Pi (DietPi Distro — Jessie), и я использую данные GPS для обновления системного времени при загрузке. Код прост, однако, он дает сбой или блокирует приложение примерно в 50% случаев. Никаких исключений не выдается, и я попытался записать любой stderr в файл журнала безуспешно. Иногда я вижу ошибку сегментации, но я думаю, что это может быть не связано.
Часть кода, которая явно вызывает сбой — это «settimeofday (&tv, NULL) «. Я могу закомментировать только это, и он будет работать нормально, но вот фрагмент кода, который присваивает timeval ‘tv’ и изменяет системное время:
//Convert gps_data_t* member 'time' to timeval
timeval tv;
double wholeseconds, decimalseconds, offsettime;
offsettime = gpsdata->fix.time - (5.0 * 3600.0);
decimalseconds = modf(offsettime, &wholeseconds);
tv.tv_sec = static_cast<int32_t>(wholeseconds);
tv.tv_usec = static_cast<int32_t>(decimalseconds * 1000000.0);
//Set system time - THIS IS CAUSING CRASHES, WHY?
if ( settimeofday(&tv, NULL) >= 0) {
std::cout << "Time set successful!" << '\n';
} else {
std::cout << "Time set failure!" << '\n';
}
Я хотел бы отметить, что установка времени успешна, когда происходит сбой системы. Я видел его неудачным в случае, когда gpsdata-> fix.time равен ‘NaN’, и он, кажется, хорошо справляется с этим и просто сообщает об ошибке. Мои собственные теории возможных причин:
Это многопоточная программа, где несколько других потоков находятся в
состояние сна (широко используется std :: this_thread :: sleep_for ()). Есть ли
изменение системного времени, пока эти потоки находятся в состоянии сна
мешать со временем он выходит из сна?Я знаю, что в дистрибутиве Debian есть служба времени (NTP?), Которая
управляет синхронизацией системного времени. Может ли это мешать?
В любом случае, мне нужно еще кое-что поэкспериментировать, но кажется, что кто-то сразу узнает. Все советы приветствуются.
Несколько других моментов, за которыми я следил этот ссылка для удаления службы ntpd, и проблема все еще остается, решая, что причина. Кроме того, я нашел этот ссылка, которая говорит, что изменение системного времени во время спящего потока не влияет, когда он просыпается. Так что теперь мои две теории расстреляны. Любые другие идеи приветствуются!
Из-за случайной ошибки сегментации, которая не ясна, связано ли это с зависанием / сбоем или нет, я продолжил и обновил код, чтобы предотвратить единственный источник неопределенного поведения, который я мог идентифицировать. Поэтому я добавил равномерную инициализацию для всех переменных, используемых в функции modf, и сделал мой timeval const. Также изменен тип приведений согласно совету ниже. Поведение остается прежним.
//Loop until first GPS lock to set system time
while ( (gpsdata == NULL) ||
(gpsdata->fix.mode <= 1) ||
(gpsdata->fix.time < 1) ||
std::isnan(gpsdata->fix.time) ) {
gpsdata = gps_rec.read();
}
//Convert gps_data_t* member 'time' to timeval
double offsettime{ gpsdata->fix.time - (5.0 * 3600.0) }; //5.0 hr offset for EST
double seconds{ 0.0 };
double microseconds{ 1000000.0 * modf(offsettime, &seconds) };
const timeval tv{ static_cast<time_t>(seconds),
static_cast<suseconds_t>(microseconds) };
//Set system time - THIS IS CAUSING CRASHES, WHY?
if ( settimeofday(&tv, NULL) >= 0) {
std::cout << "Time set successful!" << '\n';
} else {
std::cout << "Time set failure!" << '\n';
}
Задача ещё не решена.
Других решений пока нет …