QThread :: sleep не работает правильно при изменении системного времени - PullRequest
0 голосов
/ 26 апреля 2018

Пожалуйста, помогите мне решить эту проблему.

Я создаю приложение QT с QThread.В функции запуска используйте QThread :: sleep в цикле while (1).Я ставлю qDebug перед вызовом сна.Когда я запускаю программу.журнал сна будет распечатываться каждую 1 секунду.После этого я изменяю системное время командой timedatectl set-time '2015-11-23 08:10:40'.Теперь журнал «сна» больше не распечатывается!

void TestThread::run()
{
    while (1) {
        qDebug() << "sleep";
        sleep(1);
    }
}

Спасибо за помощь!

Ответы [ 2 ]

0 голосов
/ 27 апреля 2018

После изучения исходного кода я обнаружил, что QThread :: sleep имеет реализацию:

void QThread::sleep(unsigned long secs)
{
    struct timeval tv;
    gettimeofday(&tv, 0);
    struct timespec ti;
    ti.tv_sec = tv.tv_sec + secs;
    ti.tv_nsec = (tv.tv_usec * 1000);
    thread_sleep(&ti);
}

static void thread_sleep(struct timespec *ti)
{
    pthread_mutex_t mtx;
    pthread_cond_t cnd;

    pthread_mutex_init(&mtx, 0);
    pthread_cond_init(&cnd, 0);

    pthread_mutex_lock(&mtx);
    (void) pthread_cond_timedwait(&cnd, &mtx, ti);
    pthread_mutex_unlock(&mtx);

    pthread_cond_destroy(&cnd);
    pthread_mutex_destroy(&mtx);
}

следуйте этой теме https://linux.die.net/man/3/pthread_cond_timedwait. Если поддерживается опция выбора часов, переменная условия должна иметь атрибут clock, который указывает часы, которые должны использоваться для измерения времени, указанного в аргументе abstime. Когда происходят такие таймауты, pthread_cond_timedwait () тем не менее должен освободить и повторно получить мьютекс, на который ссылается мьютекс. Функция pthread_cond_timedwait () также является точкой отмены.

Так что, если я переключу систему на проход, функция сна будет спать до тех пор, пока не встретится> = системное время начала сна + период сна.

0 голосов
/ 26 апреля 2018

По вашему опыту QThread :: sleep не реализован против некоторых устойчивых часов, поэтому движение назад во времени не работает, как вы ожидаете.

Итак, вопрос: что вы хотите? Функциональность сна, которая защищена от изменений во времени? Затем реализуйте некоторую функцию в своем производном классе QThread, который сохраняет текущий момент времени как http://en.cppreference.com/w/cpp/chrono/steady_clock и затем проверяет это. Если с момента последнего вызова прошло достаточно секунд. Конечно, это активное ожидание, и его следует уточнить, передав элемент управления вместо выполнения другого цикла.

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