Форум программистов, компьютерный форум, киберфорум
C/С++ под Linux
Войти
Регистрация
Восстановить пароль
Блоги Сообщество Поиск Заказать работу  
 
Рейтинг 4.75/16: Рейтинг темы: голосов - 16, средняя оценка - 4.75
0 / 0 / 0
Регистрация: 15.06.2011
Сообщений: 10

Отменяемые таймеры

15.06.2011, 17:01. Показов 3371. Ответов 14
Метки нет (Все метки)

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

Я это пытался сделать с помощью clock_gettime / pthread_cond_timedwait
Не очень успешно. Оно в принципе работает, но есть проблема.
Работает только с CLOCK_REALTIME и категорически не желает работать с CLOCK_MONOTONIC.
Поскольку CLOCK_REALTIME страдает при смене системного времени этот вариант к использованию непригоден.

Что можно придумать для решения такой задачи ?
0
cpp_developer
Эксперт
20123 / 5690 / 1417
Регистрация: 09.04.2010
Сообщений: 22,546
Блог
15.06.2011, 17:01
Ответы с готовыми решениями:

Таймеры
Здравствуйте, хочу сделать поле в которое вводят текст и не надо нажимать enter. Ставлю обработчики на события keyup и keydown. Но они...

Таймеры
подскажите пожалуйста, не могу разобраться как правильно выставить таймеры событий. Условие: 2 канала основной и резервный, если на...

Таймеры
У меня опять вопрос по кишкам винды и книжке Марка Руссиновича (6 издание "Внутреннее устройство MS Windows") Системное время...

14
1259 / 650 / 44
Регистрация: 06.02.2011
Сообщений: 1,654
15.06.2011, 17:50
Гляньте на timer_create
1
0 / 0 / 0
Регистрация: 15.06.2011
Сообщений: 10
15.06.2011, 17:55  [ТС]
Цитата Сообщение от g_u_e_s_t Посмотреть сообщение
Гляньте на timer_create
Это было первое что у меня заработало.
Мне нужно в произвольный момент менять время срабатывания уже запущенного таймера.
0
1259 / 650 / 44
Регистрация: 06.02.2011
Сообщений: 1,654
15.06.2011, 18:01
А чем timer_settime не годиться для этой мисии???
1
0 / 0 / 0
Регистрация: 15.06.2011
Сообщений: 10
16.06.2011, 07:51  [ТС]
Цитата Сообщение от g_u_e_s_t Посмотреть сообщение
А чем timer_settime не годиться для этой мисии???
Как оно себя ведет при смене системного времени ? В мане написано что POSIX per-process timer подвержен изменению даты/времени. Изменение системного времени в процессе работы программы у меня БУДЕТ. Соответственно если таймер или ожидание не умеют использовать клок эквивалентный CLOCK_MONOTONIC или лучше CLOCK_MONOTONIC_RAW то они для моих целей не годятся и про их существование можно даже не вспоминать.
0
1259 / 650 / 44
Регистрация: 06.02.2011
Сообщений: 1,654
16.06.2011, 09:38
Ведет себя ровно как написано в манах. CLOCK_MONOTONIC умеет и это тоже написано в мане... Про CLOCK_MONOTONIC_RAW ни чего сказать не могу, тк всеми силами стараюсь избегать линуксячих изобретений.
0
0 / 0 / 0
Регистрация: 15.06.2011
Сообщений: 10
20.06.2011, 10:20  [ТС]
Цитата Сообщение от g_u_e_s_t Посмотреть сообщение
Ведет себя ровно как написано в манах. CLOCK_MONOTONIC умеет и это тоже написано в мане... Про CLOCK_MONOTONIC_RAW ни чего сказать не могу, тк всеми силами стараюсь избегать линуксячих изобретений.
Сделал через timer_settime. CLOCK_MONOTONIC работает, про CLOCK_MONOTONIC_RAW glibc ничего не знает, хотя в ядре есть.

Теперь следующий вопросик.
В каком случае меньше побочные расходы процессорного времени при срабатывании таймера - при вызове таймерной функции с созданием нити (параметр SIGEV_THREAD) или если я вручную создам таймерную нить которая будет сидеть в sigwait ожидая аларм а в таймере будет посылаться SIGALRM конкретной нити (параметр SIGEV_THREAD_ID с заданием конкретного TID) ?
Сейчас у меня работает второй вариант.
0
1259 / 650 / 44
Регистрация: 06.02.2011
Сообщений: 1,654
20.06.2011, 11:23
или если я вручную создам таймерную нить которая будет сидеть в sigwait ожидая аларм а в таймере будет посылаться SIGALRM конкретной нити (параметр SIGEV_THREAD_ID с заданием конкретного TID) ?
Честно, не понял, как именно вы сделали... Точнее не понимаю зачем вам отдельная "таймерная" нить и почему раз уж решили делать linux only сразу не указывать tid нужной нити. Ну да вам ваши нужды виднее.

Да, думаю это дешевле чем SIGEV_THREAD
0
0 / 0 / 0
Регистрация: 15.06.2011
Сообщений: 10
20.06.2011, 11:44  [ТС]
Цитата Сообщение от g_u_e_s_t Посмотреть сообщение
Честно, не понял, как именно вы сделали... Точнее не понимаю зачем вам отдельная "таймерная" нить и почему раз уж решили делать linux only сразу не указывать tid нужной нити. Ну да вам ваши нужды виднее.
Сейчас у меня сделано как вы описали. Таймерная нить при запуске определяет свой TID, передает его основной нити и при создании таймера задается TID куда посылать сигнал. (не нашел как pthread_t преобразовать в TID)

Да, думаю это дешевле чем SIGEV_THREAD
Я тоже подумал что на создание нити система может затрачивать дополнительное время.

Делаю массив таймеров для отработки таймаутов в коммуникационном протоколе. Таймеров нужно примерно две сотни.
0
1259 / 650 / 44
Регистрация: 06.02.2011
Сообщений: 1,654
20.06.2011, 12:07
Цитата Сообщение от John-11 Посмотреть сообщение
Делаю массив таймеров для отработки таймаутов в коммуникационном протоколе. Таймеров нужно примерно две сотни.
Пару лет назад, в похожей задаче (протокол поверх UDP) обошлись 4 интервальными таймерами и сортированным списком таймаутов.
0
0 / 0 / 0
Регистрация: 15.06.2011
Сообщений: 10
20.06.2011, 12:12  [ТС]
Цитата Сообщение от g_u_e_s_t Посмотреть сообщение
Пару лет назад, в похожей задаче (протокол поверх UDP) обошлись 4 интервальными таймерами и сортированным списком таймаутов.
Таймер у меня используется один а весь массив я не сортирую, лишь нахожу ближайшее время срабатывания и взвожу таймер на это время.
0
1259 / 650 / 44
Регистрация: 06.02.2011
Сообщений: 1,654
20.06.2011, 12:17
То же вариант, со своими плюсами и минусами) У вас больше сисколов на установку таймера, у меня холостые срабатывания, повторюсь, вам виднее как в вашей ситуации будет лучше)
0
0 / 0 / 0
Регистрация: 15.06.2011
Сообщений: 10
22.06.2011, 12:22  [ТС]
Не все гладко оказалось.
У меня сигнал генерится дважды: немедленно при взводе таймера функцией timer_settime и по истечении заданного таймаута. Таймеры у меня однократные.
Пришлось в обработчик сигнала вставить проверку сколько осталось до срабатывания таймера
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
void *TimerThFunc(void* ptr)
{
  int sig;
  struct timespec tsp;
  struct itimerspec curr_value;
  sigset_t signal_set;
  if (TimerThreadPid ==0)
  {
    TimerThreadPid=syscall(SYS_gettid);
    sigemptyset(&signal_set);
    sigaddset(&signal_set, SIGALRM);
    sem_post(&TimerSem);
  }
  do
  {
    sigwait(&signal_set, &sig);
    if (sig ==SIGALRM)
    {
      clock_gettime(TIMER_CLOCK_SOURCE, &tsp);
      printf("[SIGALRM:%d]\t", tsp.tv_sec);
      timer_gettime(Timer, &curr_value);
      if ((curr_value.it_value.tv_sec) ==0 && (curr_value.it_value.tv_nsec==0) )
        TimerSetNext(true);
      else
        printf("False timer alarm %d.%d\n", (int)curr_value.it_value.tv_sec,
               curr_value.it_value.tv_nsec);
    }
  }
  while (1);
  return NULL;
}
0
1259 / 650 / 44
Регистрация: 06.02.2011
Сообщений: 1,654
22.06.2011, 14:54
Если у вас не TIMER_ABSTIME, то покажите как timer_settime() делаете, а если оно, то уж простите, вы сами себе проблему на ровном месте создаете.
0
0 / 0 / 0
Регистрация: 15.06.2011
Сообщений: 10
22.06.2011, 16:00  [ТС]
Цитата Сообщение от g_u_e_s_t Посмотреть сообщение
Если у вас не TIMER_ABSTIME,
У меня TIMER_ABSTIME. Запускаю таймер так:
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
/* Запускает таймер на ближайшее время срабатывания,
 * посылает сообщение о срабатывании предыдущего времени
 *      PostEvent
 *      true - посылать событие; false - не посылать
 */
void TimerSetNext(bool PostEvent)
{
  int j, jm;
  wakeuptime_t min;
 
  struct timespec now1;
  struct itimerspec timer_values;
  timer_element_t* pointer;
  vector<timer_element_t*>::iterator ib;
  vector<timer_element_t*>::iterator ie;
  vector<timer_element_t*>::iterator imin;
  //printf("TimerSetNext %d\n", (int)PostEvent);
 
    TimerLock();
 
    if (CurrentTimer.Started)
    {
      pointer=*(CurrentTimer.TimerElementIt);
      // удалим найденный элемент
      TimerVector.erase(CurrentTimer.TimerElementIt);
    }
    else
      pointer=NULL;
 
    if (!TimerVector.empty())
    {
      // ищем минимальное значение - это будет следующий таймаут
      min.tv_sec = TIME_T_MAX;
      min.tv_nsec = LONG_MAX;
      j=jm=0;
      ie=TimerVector.end();
      // printf("TimerVector.size=%d\t",TimerVector.size());
      for (ib=TimerVector.begin(); ib != ie; ++ib)
      {
        if ( timespec_compare((struct timespec *)&((*ib)->Time.tv_sec),
            (struct timespec *)&min) < 0)
        {
          min=(*ib)->Time;
          imin=ib;
          jm=j;
        }
        ++j;
      }
      //   printf(" jm=%d\n", jm);
      // сохраним только что запущенный элемент
      CurrentTimer.TimerElementIt=imin;
      CurrentTimer.Started=true;
      // здесь имеем
      // pointer - указатель на сработавший таймер
      // min - время в которое должен сработать таймер в следующий раз
    }
    else   // активных таймеров нет, запускаем фоновый таймер
    {
      CurrentTimer.Started=false;
      clock_gettime(TIMER_CLOCK_SOURCE, &now1);
      min=now1;
      min.tv_sec=min.tv_sec + 10;
      //printf("no active timers\n");
    }
    timer_values.it_value=min;
    timer_values.it_interval.tv_sec = 0;
    timer_values.it_interval.tv_nsec = 0;
    timer_settime (Timer, TIMER_ABSTIME /*0*/, &timer_values, NULL);
    TimerUnlock(); // перед отправкой сообщения нужно разблокировать таймер
    if (PostEvent)
    {
      TimerPostEvent(pointer);
    }
}
0
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
raxper
Эксперт
30234 / 6612 / 1498
Регистрация: 28.12.2010
Сообщений: 21,154
Блог
22.06.2011, 16:00
Помогаю со студенческими работами здесь

Таймеры
Здравствуйте, скажите какие есть готовые таймеры? Пользовался поиском, нашел только winapi и простую библиотеку time.h, только почему то...

Таймеры
Здравствуйте. Можно ли получить с ножки МК прямоугольные импульсы с определенной частотой(до 1кГц) не вмешиваясь в основную программу.

таймеры
проблема с таймарами!!! Вот реализация 2-ух таймаров(один из них закоментирован) //void CALLBACK TimerProc(UINT uTimerID, UINT uMsg,...

Таймеры
Нужно зачудить такое: Каждые 500 мс. нужно менять картинку в image1. Image1.Picture.LoadFromfile ('1.jpg'); ...

Таймеры в Mysql
Добрый день. Мне нужно выполнять некую процедуру на mysql servere с некой периодичностью или же чтоб сия функция постоянно крутилась...


Искать еще темы с ответами

Или воспользуйтесь поиском по форуму:
15
Ответ Создать тему
Новые блоги и статьи
Вывод диалогового окна перед закрытием, если документ не проведён
Maks 04.04.2026
Алгоритм из решения ниже реализован на примере нетипового документа "СписаниеМатериалов", разработанного в конфигурации КА2. Задача: реализовать программный контроль на предмет проведения документа. . .
Программный контроль заполнения реквизита табличной части документа
Maks 02.04.2026
Алгоритм из решения ниже реализован на примере нетипового документа "СписаниеМатериалов", разработанного в конфигурации КА2. Задача: реализовать контроль заполнения реквизита "ПричинаСписания". . .
wmic не является внутренней или внешней командой
Maks 02.04.2026
Решение: DISM / Online / Add-Capability / CapabilityName:WMIC~~~~ Отсюда: https:/ / winitpro. ru/ index. php/ 2025/ 02/ 14/ komanda-wmic-ne-naydena/
Программная установка даты и запрет ее изменения
Maks 02.04.2026
Алгоритм из решения ниже реализован на примере нетипового документа "СписаниеМатериалов", разработанного в конфигурации КА2. Задача: при создании документов установить период списания автоматически. . .
Вывод данных в справочнике через динамический список
Maks 01.04.2026
Реализация из решения ниже выполнена на примере нетипового справочника "Спецтехника" разработанного в конфигурации КА2. Задача: вывести данные из ТЧ нетипового документа. . .
Программное заполнения текстового поля в реквизите формы документа
Maks 01.04.2026
Алгоритм из решения ниже реализован на нетиповом документе "ВыдачаОборудованияНаСпецтехнику" разработанного в конфигурации КА2, в дополнении к предыдущему решению. На форме документа создается. . .
К слову об оптимизации
kumehtar 01.04.2026
Вспоминаю начало 2000-х, университет, когда я писал на Delphi. Тогда среди программистов на форумах активно обсуждали аккуратную работу с памятью: нужно было следить за переменными, вовремя. . .
Идея фильтра интернета (сервер = слой+фильтр).
Hrethgir 31.03.2026
Суть идеи заключается в том, чтобы запустить свой сервер, о чём я если честно мечтал давно и давно приобрёл книгу как это сделать. Но не было причин его запускать. Очумелые учёные напечатали на. . .
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2026, CyberForum.ru