Как реализовать таймер в C на окнах - PullRequest
6 голосов
/ 17 сентября 2009

Как мне создать таймер в C, и по истечении этого времени я смогу вызвать функцию обратного вызова. Платформа оконная.

Может ли кто-нибудь направить меня

С уважением, Митхун

Ответы [ 8 ]

8 голосов
/ 17 сентября 2009

Взгляните на функцию SetTimer .

UINT_PTR timerid = SetTimer(NULL, 0, milliseconds, &callback);
1 голос
/ 21 сентября 2009

С Таймеры и действия по умолчанию :

/* ** TIMEGETC.C - waits for a given number of seconds for the user to press ** a key.     Returns the key pressed, or EOF if time expires ** ** by Bob Jarvis */

#include <stdio.h>
#include <time.h> 
#include <conio.h>

int timed_getch(int n_seconds) 
{
   time_t start, now;

   start = time(NULL); now = start;

   while(difftime(now, start) < (double)n_seconds && !kbhit()) { now = time(NULL); }

   if(kbhit()) 
       return getch(); 
   else 
       return EOF;
}

void main(void)
{
   int c;

   printf("Starting a 5 second delay...\n");

   c = timed_getch(5);

   if(c == EOF)
       printf("Timer expired\n");
   else 
       printf("Key was pressed, c = '%c'\n", c);
}

Но я бы рассмотрел использование Window :: SetTimer (), как упомянуто выше ...

1 голос
/ 17 сентября 2009

сигнализация делает это (на платформах POSIX).

0 голосов
/ 17 сентября 2009

Возможно, это немного не соответствует цели, и это C ++, а не C, но вот моя реализация очереди таймера для Windows с тестами и комментариями по TDD. Обратите внимание, что в первой части серии объясняется, почему я решил бросить свою собственную, а не использовать альтернативы.

http://www.lenholgate.com/blog/2004/05/practical-testing.html

0 голосов
/ 17 сентября 2009

Один из способов сделать это - вызвать SetTimer, а затем обработать событие WM_TIMER в вашем WndProc. Например, это установит таймер, который вызывается каждые 45 секунд и отображает окно сообщения при его вызове:

LRESULT CALLBACK WndProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
{
    switch(message)
    {
        case WM_CREATE:
            SetTimer(hwnd, 1, 45000, NULL);
            break;

        case WM_TIMER:
            MessageBox(hwnd, L"Timer", L"Timer fired!", MB_OK);
            break;
    }
    return DefWindowProc(hwnd, message, wParam, lParam);
}

Первым параметром SetTimer является окно, в которое вы хотите получить сообщение WM_TIMER - вы, вероятно, хотите, чтобы это было ваше окно, поэтому вы можете просто передать hwnd, что окна передали вам.

Второй параметр - это число, которое вы можете использовать для однозначной идентификации таймера. Вы можете использовать более одного таймера одновременно, и вам потребуется способ узнать, какой из них сработал.

Третий параметр - это как долго вы хотите, чтобы таймер подождал до его срабатывания. Это в миллисекундах, так что вы должны умножить на тысячу, если хотите секунды.

Четвертый параметр равен NULL, если вы хотите обработать таймеры, посмотрев на WM_TIMER. В противном случае вы можете передать указатель на функцию обратного вызова, которая будет вызываться вместо этого.

Помните, таймер будет продолжать срабатывать каждые X миллисекунд, пока вы не убьете его. Вы можете убить его, вызвав KillTimer и передавая тот же номер, который вы передали второму параметру при вызове SetTimer.

Кроме того, когда Windows отправляет вам сообщение WM_TIMER, wParam будет содержать идентификатор таймера, который вы передали во втором параметре при вызове SetTimer.

0 голосов
/ 17 сентября 2009

Если вам не нужно ничего делать в вашем приложении, вы можете использовать функцию sleep () . Он прекратит выполнение и продолжит выполнение кода после истечения заданной продолжительности (ish).

В Windows мы использовали функцию мультимедийного таймера, если вы хотели спать не более одной секунды. Некоторые другие методы зависят от платформы.

Я также слышал о людях, использующих select () в качестве метода сна в течение милли / микросекунд.

Если вам нужно, чтобы что-то происходило, вы хотите использовать режим сна / выбора во втором потоке.

Вот библиотека Google для выполнения синхронизации высокого разрешения . Это может помочь.

0 голосов
/ 17 сентября 2009

Если вы хотите использовать WIN32 Thread Pools , вы можете использовать таймеры пула потоков.

Пул потоков - это коллекция рабочих потоков, которые эффективно выполняют асинхронные обратные вызовы от имени приложения. Пул потоков в основном используется для уменьшения количества потоков приложений и обеспечения управления рабочими потоками. Приложения могут ставить рабочие элементы в очередь, связывать работу с ожидаемыми дескрипторами, автоматически ставить в очередь на основе таймера и связывать с вводом / выводом.

Часть этого API, см.

CreateTimerQueueTimer Функция

Создает таймер очереди таймера. Этот таймер истекает в указанное время, затем после каждого указанного периода. Когда таймер истекает, вызывается функция обратного вызова.

0 голосов
/ 17 сентября 2009

Таймеры не являются частью языка C.

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

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