LINUX.ORG.RU

реализация таймера (+)


0

0

понадобилось мне сделать выполнение некоторых
функций через определенное время
пока приходит на ум такая схема
сделать таблицу указателей на функции
с параметром через какое время из запускать
в момент добавления делать
exectime = time(NULL) + delay;
и в цикле проверять
if(time(NULL) > exectime) *(fn)();
но у данной схемы есть 3 недостатка
1 если вдруг юзер во время работы проги переведет время
то все задержки сместятся и получиться кавардак
2 выполняемые функции должны иметь одинаковый вид
(т.е. теряется некая универсальность того что надо выполнить)
3 точность, цикл вожможен в виде
while(1){
do_checks();
sleep(sometime);
}
т.е. чтоб увеличить точность надо уменьшить время слипа
но это будет грузить проц... в моем случает это не особо
критично, точность даже в пару секунд устраивает
но всеже интересно как сделать эфективнее...
может быть кто-то подскажет схему реализации избавленую
от этих недостатков ? или пути обхождения их
в предложенном варианте ?
P.S. функций может быть довольно много (10-30)

anonymous

setitimer не подойдет?

ставим таймаут до ближайшего события, по приходу сигнала пускаем функцию, потом устанавливаем таймаут до следующего события и т.д.

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

Народ, у меня задача посложней: поставить таймер на чтение из сокета. Который останавливается, когда в сокет что-то приходит (другими словами, когда меняется дескриптор этого сокета). select() с таймаутом не подходит - он не работает параллельно с процедурой recv(из сокета).

Кто имеет идеи, просьба высказываться.

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

можно примерно так
struct sigaction act;
act.sa_handler = sig_alarm;
act.sa_flags = SA_RESETHAND;
sigaction(SIGALRM, &act, 0)
alarm(timeout);
if(connect (... ) < 0){
         if(errno == EINTR){
            printf("timed out\n");            
            exit(-1);
         } else {
            perror("Error in connect");
            exit(-1)
         }
}
alarm(0);

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

Для recv() смотрим setsockopt() с параметром SO_RECVTIMEO... правда дело в том, что я не знаю, какая ошибка при этом возвращается... кто-нить подскажет. И возвращается ли ошибка вообще по истечении времени? Мне нужно...

А примерно так:

setsockopt(sock_descriptor, SOL_SOCKET, SO_RECVTIMEO, &timeout, sizeof(timeout));

Люди, знает кто, что будет, если такое сделать?

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

мот я че путаю но вобще это в винде работает
типа
int tm = 300;
setsockopt(Sock, SOL_SOCKET, SO_RCVTIMEO, (char *)&tm, sizeof(int));
а в линуксе такого нету, и таймауты надо другими схемами
типа предложеной Dead реализовывать....


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

2 Murr
спасибо за саму идею организации цепочки
как-то не подумал о таком варианте...
а setitimer не подходит, т.к. SIGALARM используется
уже для реализации других механизмов...

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

timer_create? Можно прикрутить таймер к любому сигналу, на rt-сигнал можно повесить несколько таймеров.

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

Не путаете. В винде такое тоже есть...

Только вот и во фрях есть точно. Ман же есть! Пара процедур: getsockopt() и setsockopt().

Только я почему-то уверена, что работают они в двух осах по-разному.

Сейчас вот сяду и попробую разобраться. Если что - потом расскажу :)

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