LINUX.ORG.RU

Цикл по таймеру на языке Си.


0

1

Помогите реализовать фрагмент кода, который должен повторяться каждые 60 секунд. Я (неправильно, по-видимому) делаю так:

/*
ptime структура, содержащая дату и время, 
разбитые на компоненты
tm_sec - секунды
tm_min - минуты
*/
while((ptime->tm_sec)%60 == 0)
{
...                  // фрагмент который нужно
...                  // повторять каждые 60с
}
При такой формулировке, цикл выполняется один раз, а мне нужно чтобы бесконечно, каждые 60 секунд.

Ответ на: комментарий от x0r

а если он запустит программу, когда на компе будет 34с? тогда цикл выполнится только через 26с...

int old_secs, new_secs;
old_secs = new_secs = ...// Получаем время
while(1) {
    if((new_secs - old_secs) % 60 == 0) {
        // твои действия
    }
    new_secs =  ...// Получаем время
}
energyclab
()
Последнее исправление: energyclab (всего исправлений: 1)
Ответ на: комментарий от x0r

Работает. Фрагмент выполняется каждые 60 секунд, но выполняется он столько раз, сколько успевает выполнится за секунду.

while(1)
{
    get_time();
    if((ptime->tm_sec)%5 == 0)
    {
        printf("Одна строка");
    }
}
результат:
на строкаОдна строкаОдна строкаОдна строкаОдна строкаОдна строкаОдна строкаОдна строкаОдна строкаОдна строкаОдна строкаОдна строкаОдна строкаОдна строкаОдна строкаОдна строкаОдна строкаОдна строкаОдна строкаОдна строкаОдна строкаОдна строкаОдна строкаОдна строкаОдна строкаОдна строкаОдна строкаОдна строкаОдна строкаОдна строкаОдна строкаОдна строкаОдна строкаОдна строкаОдна строкаОдна строкаОдна строкаОдна строкаОдна строкаОдна строкаОдна строкаОдна строкаОдна строкаОдна строкаОдна строкаОдна строкаОдна строкаОдна строкаОдна строкаОдна строкаОдна строкаОдна строкаОдна строкаОдна строкаОдна строкаОдна строкаОдна строкаОдна строкаОдна строкаОдна строкаОдна строкаОдна строкаОдна строкаОдна строкаОдна строкаОдна строкаОдна строкаОдна строкаОдна строкаОдна строкаОдна строкаОдна строкаОдна строкаОдна строкаОдна строкаОдна строкаОдна строкаОдна строкаОдна строкаОдна строкаОдна строкаОдна строкаОдна строкаОдна строкаОдна строкаОдна строкаОдна строкаОдна строкаОдна строкаОдна строкаОдна строкаОдна строкаОдна строкаОдна строкаОдна строкаОдна строкаОдна строкаОдна строкаОдна строкаОдна строкаОдна строкаОдна строкаОдна строкаОдна строкаОдна строкаОдна строкаОдна строкаОдна строкаОдна строкаОдна строкаОдна строкаОдна строкаОдна строкаОдна строкаОдна строкаОдна строкаОдна строкаОдна строкаОдна строкаОдна строкаОдна строкаОдна строкаОдна строкаОдна строкаОдна строкаОдна строкаОдна строкаОдна строкаОдна строкаОдна строкаОдна строкаОдна строкаОдна строкаОдна строкаОдна строкаОдна строкаОдна строкаОдна строкаОдна строкаОдна строкаОдна строкаОдна строкаОдна строкаОдна строкаОдна строкаОдна строкаОдна строкаОдна строкаОдна строкаОдна строкаОдна строкаОдна строкаОдна строкаОдна строк

podovalov5
() автор топика
Ответ на: комментарий от podovalov5

Ясен пень: ты ж миллисекунды не учитываешь!

Советую вот как сделать:

double dtime(){
    double t;
    struct timeval tv;
    gettimeofday(&tv, NULL);
    t = tv.tv_sec + ((double)tv.tv_usec)/1e6;
    return t;
}

// main:
   double Oldt = dtime(), Newt = Oldt;
   ...
   do{
      Newt = dtime();
      if(Newt - Oldt > 60.){
          Oldt = Newt;
          // делай то, что нужно каждую минуту пускать
      }
      // чтобы не грузить процессор, можно добавить select секунд на 5-10 или тупо sleep
   }while(1);
Eddy_Em ☆☆☆☆☆
()
#include <unistd.h>
int main()
{
	for (;;)
	{
		int left = 60;
		while (left != 0)
		{
			left = sleep(left);
		}
		puts("It's time!");
	}
}
tim239 ★★
()
Ответ на: комментарий от beastie
The certificate is not trusted because it is self-signed.

Ссылка на https с самоподписанным сертификатом при живом http? Зачем, интересно? На лоровцах ставят эксперименты? :-)

anonymous
()
Ответ на: комментарий от wakuwaku

Async-signal-safe functions

A signal handler function must be very careful, since processing elsewhere may be interrupted at some arbitrary point in the execution of the program. POSIX has the concept of «safe function». If a signal interrupts the execution of an unsafe function, and handler calls an unsafe function, then the behavior of the program is undefined.

four_str_sam
()
Ответ на: комментарий от anonymous

Забыл 's' убрать.

А вообще, одна из причин: http://www.informationweek.com/software/information-management/yes-trust-in-t...

Линк хоть и старый, но всё ещё в какой-то степени актуальный. Т.к. с ssl регулярные f*ckup'ы случаются. И вообще он просто broken by design.

Т.ч. шифрование — да, pki — нет, спасибо, мы как-нибудь сами. ;)

beastie ★★★★★
()
Ответ на: комментарий от four_str_sam

Ты хотя бы в код заглянул, что ли. Я ведь не зря весь код, а не только sniplets, привёл. ;)

В обработчике меняются только флаги:

#include <sys/time.h>
#include <signal.h>
#include <stdio.h>

int gotalrm = 0;

void
catch(int sig)
{
        if (sig == SIGALRM)
                gotalrm = 1;
}

int
main()
{
        struct sigaction sa;
        struct itimerval it;

        sigemptyset(&sa.sa_mask);
        sa.sa_flags = 0;
        sa.sa_handler = catch;
        sigaction(SIGALRM, &sa, NULL);

        it.it_value.tv_sec = 1;
        it.it_value.tv_usec = 0;
        it.it_interval = it.it_value;
        setitimer(ITIMER_REAL, &it, NULL);

        for (;;) {
                if (gotalrm) {
                        puts("dong");
                        gotalrm = 0;
                }
                sigsuspend(&sa.sa_mask);
        }

        return 0;
}

PS: поправил для полноты картины.

beastie ★★★★★
()
Последнее исправление: beastie (всего исправлений: 2)
Ответ на: комментарий от AIv

А простого sleep без всех этих навротов не достаточно?;-)

Нет, т.к. без time() ты более-менее точно интервал между запусками не выставишь!

Eddy_Em ☆☆☆☆☆
()
Ответ на: комментарий от Eddy_Em

Можно тогда nanosleep() вместо sleep(), для точности.

tim239 ★★
()
Ответ на: комментарий от AIv

Да ладно, с точностью до секунды вполне

ТС же хочет не через 60 сек после окончания предыдущей итерации, а начинать каждые 60 сек. Или ты уверен, что его код гарантировано уложится в секунду?

monk ★★★★★
()
Ответ на: комментарий от monk

Ок. Правда что делать если оно не уложится в 60?;-)

AIv ★★★★★
()
Ответ на: комментарий от energyclab

то, что я ему привел - вообще не production код.

x0r ★★★★★
()
Ответ на: комментарий от AIv

Потом от этих циклослипов и кончается батарейка на ноутбуке.

NikolaSh
()
Ответ на: комментарий от AIv

А если запускаемый процесс длится много секунд?

Eddy_Em ☆☆☆☆☆
()
Ответ на: комментарий от anonymous

Очень благодарен всем за помощь. У себя использовал совет Eddy_Em.

podovalov5
() автор топика
Вы не можете добавлять комментарии в эту тему. Тема перемещена в архив.