Russian Qt Forum
Ноябрь 27, 2024, 03:38 *
Добро пожаловать, Гость. Пожалуйста, войдите или зарегистрируйтесь.
Вам не пришло письмо с кодом активации?

Войти
 
  Начало   Форум  WIKI (Вики)FAQ Помощь Поиск Войти Регистрация  

Страниц: [1]   Вниз
  Печать  
Автор Тема: usleep() usage  (Прочитано 9560 раз)
yashaka
Гость
« : Февраль 18, 2010, 15:29 »

Столкнулся с такой проблемой - usleep() спит дольше чем необходимо.
Вот доказательства:)
Код:
#include <QtCore>
class SleepThread : public QThread
{
public:
    SleepThread(QObject *parent = 0) : QThread(parent)
    {
    }
    ~SleepThread()
    {
    }
protected:
    void run()
    {
        str = "1\t2\t1 000\t14 000\t15 000\t16 000\t17 000\t50 000\t100 000\t";
        qDebug() << str << endl;
        str.clear();

        for (int i = 0; i < 20; ++i) {
            testUSleep(1);
            testUSleep(2);
            testUSleep(1000);
            testUSleep(14000);
            testUSleep(15000);
            testUSleep(16000);
            testUSleep(17000);
            testUSleep(50000);
            testUSleep(100000);
            qDebug() << str << endl;
            str.clear();
        }
    }
private:
    QString str;
    QTime t1, t2;

    void testUSleep(int t)
    {
        t1 = QTime::currentTime();
        usleep(t);
        t2 = QTime::currentTime();
        str += QString::number(t1.msecsTo(t2)) + "\t";
    }

};

int main(int argc, char *argv[])
{
    QCoreApplication a(argc, argv);
    SleepThread sleeper;
    sleeper.start(QThread::TimeCriticalPriority);
    sleeper.wait();
    return a.exec();
}
Результат исполнения примера:

Код:
"1	2	1 000	14 000	15 000	16 000	17 000	50 000	100 000	" 
"0 0 0 15 32 15 16 47 109 "
"0 0 0 16 15 16 16 62 94 "
"0 15 0 16 16 15 16 47 109 "
"0 0 0 16 15 32 15 47 110 "
"0 0 0 15 16 15 16 63 93 "
"0 0 16 16 15 16 15 47 110 "
"0 0 0 15 16 16 31 47 93 "
"16 0 0 16 15 16 16 62 94 "
"0 0 0 15 32 15 16 47 109 "
"0 0 0 16 15 16 16 62 94 "
"0 16 0 15 16 15 16 47 109 "
"0 0 0 16 16 31 15 47 110 "
"0 0 0 15 16 16 15 63 93 "
"0 0 16 16 15 16 16 46 110 "
"0 0 0 15 16 16 31 47 94 "
"15 0 0 16 15 16 16 62 94 "
"0 0 0 16 31 15 16 47 109 "
"0 0 0 16 16 15 16 62 94 "
"0 16 0 15 16 16 15 47 109 "
"0 0 0 16 16 31 16 46 110 "

// В первой строке  указано время в микросекундах которое передавалось usleep()
// Соответственно в столбцах время паузы в милисекундах

Выходит на эту функцию положится нельзя?
Или это я что то не так делаю? Или QTime врет? И вообще с чем могут быть связаны такие пересыпания?
// В примере я запускаю поток с наивысшим приоритетом, так как заметил что чем он ниже тем чаще такие "выбросы", а иногда и больше...

Если это действительно проблема usleep, то как тогда мне можно сделать паузы в размере десятков микросекунд и в 1 милисекунду?
//в принципе можно циклы гонять столько сколько нужно (перед этим высчитав), но хотелось бы чего то более точного что ли...
Записан
kuzulis
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 2812


Просмотр профиля
« Ответ #1 : Февраль 18, 2010, 15:41 »

Это проблема ОС! а т.к. Ваша ОС - не из ряда RTOS  (догадываюсь Улыбающийся ) - то и положиться на точное измерение времени нельзя (ИМХО),
тем более эти паузы будут отличаться в зависимости от нагрузки на ОС...
Записан

ArchLinux x86_64 / Win10 64 bit
yashaka
Гость
« Ответ #2 : Февраль 19, 2010, 09:49 »

"Эх, жизнь моя жестянка..."Улыбающийся
Ну что же, придется как то научиться с этим жить))))
Спасибо за ответ!
Записан
SASA
Гость
« Ответ #3 : Февраль 20, 2010, 13:23 »


Если это действительно проблема usleep, то как тогда мне можно сделать паузы в размере десятков микросекунд и в 1 милисекунду?

В винде usleep вызывает Sleep(). А он приостанавливает поток - операция накладная. Переключить поток, дать поработать другим, вернуться к нашему потоку. Давно (на четвертом пне) Sleep(1) равнялось минимум 15 мсек.
Записан
Alex Custov
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 2063


Просмотр профиля
« Ответ #4 : Февраль 21, 2010, 08:44 »

sleep как правило передаёт управление в планировщике задач следующей задаче. Когда планировщик вернётся к этой задаче и установит, что она уже не спит, зависит от настроек (например в linux от CONFIG_HZ). Отсюда задача может проспать дольше, чем ей сказали через sleep. Накладность задачи тут ни при чём.
Записан
Firefox
Гость
« Ответ #5 : Март 09, 2010, 21:48 »

я вот кстати задержки реализовывала по другому,уже не помню, но со sleep что-то не так было, какой вариант лучше?
Код:
QTime t_time;
for(;t_time<elapsed(1000);)
{
qApp->processEvents();
}
Записан
Alex Custov
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 2063


Просмотр профиля
« Ответ #6 : Март 09, 2010, 21:57 »

я вот кстати задержки реализовывала по другому,уже не помню, но со sleep что-то не так было, какой вариант лучше?

Сначала нужно разобраться что не так было со sleep, т.к. данный код, естественно, - костыль.
Записан
Firefox
Гость
« Ответ #7 : Март 09, 2010, 22:06 »

ну например у еня приложение закрываться должно по нажатию на esc, если я нажимаю кнопку в момент когда работает sleep то закроется оно когда закончиться задержка. а у меня она допустим 15 секунд. и что мне ждать. в цикле всё закрывается сразу. и ещё - что такое на вашем жаргоне костыль?я конечно интуитивно понимаю, но словами не могу подобрать
Записан
Alex Custov
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 2063


Просмотр профиля
« Ответ #8 : Март 10, 2010, 00:02 »

ну например у еня приложение закрываться должно по нажатию на esc, если я нажимаю кнопку в момент когда работает sleep то закроется оно когда закончиться задержка. а у меня она допустим 15 секунд. и что мне ждать. в цикле всё закрывается сразу

значит надо пересмотреть алгоритм, возможно задержку можно заменить на сигнал-слот.
Записан
Firefox
Гость
« Ответ #9 : Март 10, 2010, 13:19 »

 у меня очень много процессов сразу работает, например один текст с задержкой меняется на другой  и всё это в таймере каждую секунду. таймер запускается по нажатию на кнопку. если у меня задержка 5 сек, то таймер просто стопариться. а так получается. а как со слотом?я не знаю такого решения. подскажите хоть в общем что за  и как работает
Записан
Igors
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 11445


Просмотр профиля
« Ответ #10 : Март 10, 2010, 16:58 »

у меня очень много процессов сразу работает, например один текст с задержкой меняется на другой  и всё это в таймере каждую секунду. таймер запускается по нажатию на кнопку. если у меня задержка 5 сек, то таймер просто стопариться. а так получается. а как со слотом?я не знаю такого решения. подскажите хоть в общем что за  и как работает
Использовать usleep не стоит (по крайней мере в UI для пользователя) по причине его тормознутости и отсутствия всякой гибкости. Нормальное решение - зарядить одиночный (или многоразовый) таймер который пошлет нужный сигнал в нужное время. При получении этого сигнала будут выполнены нужные действия.

"Костыль" на молодежном жаргоне означает - сиюминутное, "быстрое" решение проблемы, за которое, однако, придется расплачиваться в дальнейшем. "Латание дырок" вместо того чтобы сделать "капитально"
Записан
Alex Custov
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 2063


Просмотр профиля
« Ответ #11 : Март 10, 2010, 20:38 »

"Костыль" на молодежном жаргоне означает - сиюминутное, "быстрое" решение проблемы, за которое, однако, придется расплачиваться в дальнейшем.

Почему на молодёжном? Улыбающийся http://lurkmore.ru/Костыль
Записан
Страниц: [1]   Вверх
  Печать  
 
Перейти в:  


Страница сгенерирована за 0.094 секунд. Запросов: 23.