2011-01-19 3 views
4

Я искал возможное решение на многих форумах в течение нескольких дней, но не повезло; (Я отправлю свой вопрос здесь и ваш ответ очень ценитсякак реализовать функцию обратного вызова таймера в C под Linux

IDEA:. Используйте скрипт для управления освещением (в C под Linux)

ПРИМЕНЕНИЕ СЦЕНАРИЙ У меня есть три индикатора: красный, синий и зеленый. Например, Теперь через 10 секунд включите красный свет на 2 секунды: С этого момента через 15 секунд включите синюю подсветку в течение 10 секунд; С этого момента в 21 секунде , включите красный свет в течение 5 секунд, С этого момента через 5 секунд включите зеленый свет в течение 7 секунд; С этого момента через 103 секунды включите зеленый свет в течение 11 секунд; ... .. Когда и как долго включить свет абсолютно произвольно. И эта программа должна быть способна расширять до сотни световых и тысяч графиков.

КАК КОДИРОВАТЬ ИНФОРМАЦИЮ Моя идея состоит в том, чтобы иметь два процесса и один почтовый ящик: Первый процесс считывает файл сценария и анализирует графики во многих таймерах. По истечении таймера он отправляет сообщение (включая идентификатор света и действие - ВКЛ или ВЫКЛ.) В почтовый ящик. Второй процесс - включить или выключить указанный свет на основе сообщения из почтового ящика.

Каждое расписание будет разобрано на два таймера: Расписание: через 10 секунд включите красный свет на 2 секунды; Разработано для: Таймер 1: таймер истечет через 10 секунд; после истечения срока действия он передает идентификатор света (красный свет) и действие (ВКЛ) в качестве сообщения в почтовый ящик; Таймер 2: таймер истекает через (10 + 2) секунды; после истечения срока действия он передает идентификатор света (красный свет) и действие (ВЫКЛ) в качестве сообщения в почтовый ящик;

Второй процесс постоянно проверяет почтовый ящик и принимает правильное действие при правильном освещении на основе полученного сообщения.

МОЙ ВОПРОС Таймер в Linux() выпускает один и тот же сигнал SIGALRM с истекшим сроком действия. Я не могу передать идентификатор света и действие в почтовый ящик. У меня есть другой способ сделать это? Большое спасибо.

ответ

3

SIGALRM не очень надежный способ реализовать что-либо подобное, у вас не может быть более одного запроса на будильник в одно и то же время. И было ли то, что два процесса дизайна означали что-то вроде at(1)/atd (8)? К сожалению, «at» не так точен, чтобы его можно было использовать здесь, я не уверен, что он даже использует секунды, когда вы что-то планируете.

Однако проблему очень просто решить только одной программой. Просто разделите задачу на такие события, как «включить/выключить свет X», поместить их в упорядоченную очередь и иметь цикл, который читает очередь и спит, пока не приступит время действовать.

+0

+1: Правильная техника заключается в том, чтобы упорядочить события в списке (каждый из которых идентифицирует два раза и свет - время его включения и время его отключения), чтобы первое событие в порядке в начале списка. Вы можете пройти через список, ожидающий соответствующего периода между действиями. –

3

Решение Tonttu довольно хорошее.

Используйте очередь реализована с связанного списка:

struct node { 
    struct node *next; 
    time_t t;  // time to start 
    int action; // on/off 
    int lamp_id; 
}; 

struct queue { 
    struct node *head; 
    struct node *tail; 
}; 

PARSE файл и заполнить очередь (держать его отсортированы по т). Далее, ваш основной цикл должен выглядеть следующим образом:

time_t start = time(NULL); 
while(!queue_empty()) { 
    time_t now = time(NULL) - start; 
    struct node *n = queue.head;   

    if(n->t <= now) { 
     lamp(n->lamp_id, n->action); // set the status of a lamp 
     queue_next(); 
    } else { 
     sleep(n->t - now); 
    } 
} 

Как обычно, прочитайте документацию. Вам понадобится time(2). Если вам требуется суб-секунда, используйте gettimeodday(2).

+6

сон (1) и другие опросы были плохим дизайном уже много лет. Он будет тратить электроэнергию на ноутбуки или мобильные телефоны. Пожалуйста, вычитайте head-> t отныне и спать так долго. Напиши свои программы, чтобы просыпаться, когда это абсолютно необходимо. –

+0

+1 С редактированием кафе это приятное решение. – fmark

Смежные вопросы