Студопедия
Случайная страница | ТОМ-1 | ТОМ-2 | ТОМ-3
АвтомобилиАстрономияБиологияГеографияДом и садДругие языкиДругоеИнформатика
ИсторияКультураЛитератураЛогикаМатематикаМедицинаМеталлургияМеханика
ОбразованиеОхрана трудаПедагогикаПолитикаПравоПсихологияРелигияРиторика
СоциологияСпортСтроительствоТехнологияТуризмФизикаФилософияФинансы
ХимияЧерчениеЭкологияЭкономикаЭлектроника

Схемы уведомления

Читайте также:
  1. III. Составление структурной схемы системы
  2. q в любой форме (например, в виде графической схемы) составить алгоритм решения задачи, например как показано на рисунке 2.4.2;
  3. Внимание! При присвоении имен проводникам будьте ПРЕДЕЛЬНО внимательны, т.к. малейшие неточности могут привести к трудно обнаружимым ошибкам в логике работы всей схемы.
  4. Вопрос 1 Если кто-либо подает против меня иск, могу ли я потребовать уведомления?
  5. Выбор схемы и расчет концевых уплотнений
  6. Выбор схемы сборных водоводов
  7. Где должны храниться схемы тепловых энергоустановок?

Периодический или однократный таймер может несколькими способами уведомить поток о своем срабатывании.

Уведомление при помощи импульса.

Уведомление при помощи сигнала.

Уведомление путем создания потока

Рассмотрим уведомление при помощи импульса.

Независимо от выбранной схемы уведомления необходимо заполнить структуру struct sigevent.

struct sigevent{

int sigev_notify;

union{

int sigev_signo;

int sigev_coid;

int sigev_id;

void (*sigev_notify_function) (union sigval)

}

}

union sigval sigev_value;

union {

struct{

short sigev_code;

chort sigev_priority;

};

pthread_attr_t *sigev_notify_attributes;

};

Поле sigev_notify определяет выбранную схему уведомления:

SIGEV_PULSE – при срабатывании таймера будет передаваться импульс;

SIGEV_SIGNAL, SIGEV_SIGNAL_CODE или IGEV_SIGNAL_THREAD - при срабатывании таймера будет передаваться сигнал;

SIGEV_UNBLOCK – предназначен для таймаутов ядра;

SIGEV_INTR – предназначен для обработки прерываний;

SIGEV_THREAD – будет создан поток.

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

· полю sigev_notify присвоить значение SIGEV_PULSE;

· поле sigev_coid присвоить идентификатор соединения (connection ID) по каналу которого будет передан импульс;

· поле sigev_value – 32 разрядное значение, которое будет передано по заданному полем sigev_coid соединению;

· поле sigev_code – 8 – разрядное значение, которое будет передано по заданному полем sigev_coid соединению;

· поле sigev_priority – приоритет доставки импульса. Нулевое значение не допускается

Для работы с таймером необходимо выполнить следующее:

· создать объект «таймер»;

· выбрать схему уведомления;

· выбрать нужный тип таймера;

· запустить таймер.

Рассмотрим данные пункты на примере программы.

//timer.cpp

#include <stdio.h>

#include <sys/neutrino.h> //для работы с сообщениями

#include "MessageException.h" // для обработки ошибок

#include <time.h> //для работы с таймером

#include <signal.h>

#include <sys/siginfo.h>

#define MY_PULSE_TIMER 1 //импульс, передаваемый от таймера

typedef struct{

int mesType;// сообщение от клиента

char buff[512];

} ClientMessageT;

typedef union{

ClientMessageT msg;

struct _pulse pulse; //для обработки импульсов

}MessageT;

Для того чтобы можно было использовать импульсы, необходимо определить объединение, в которое входит поле struct _pulse pulse.

typedef union{

(поля объединения, определяемые пользователем)

struct _pulse pulse

}

int g_chid;//идентификатор канала

int g_NTikTimer = 0; //число отсчетов таймера

//В данной функции создается периодический таймер,

//выбирается схема уведомления с использованием импульса

int SetupTimer(void)

{

timer_t timer_id;//идентификатор таймера

struct sigevent event;//событие генерируемое таймером

struct itimerspec timer;//структура данных таймера

int coid;//идентификатор соединения

//присоединить канал для текущего процесса

coid = ConnectAttach(0, 0, g_chid, 0, 0);

if(coid == -1){

печать сообщение об ошибке присоединения канала для текущего процесса;

return -1;

}

//установить генерацию импульса

SIGEV_PULSE_INIT(&event, coid, SIGEV_PULSE_PRIO_INHERIT, MY_PULSE_TIMER, 0);

//Создать таймер

if(timer_create(CLOCK_REALTIME, &event, &timer_id) == -1){

печать сообщение об ошибке создания таймера;

return -1;

}

Для выбора типа таймера используется функция timer_settime(timer_t timerid, int flags, struct itimerspec *value, struct itimerspec *oldvalue). Агргумент timerid – идентификатор таймера. Создается при вызове фугкции timer_create.

Аргумент flags определяет тип таймера – относительный или абсолютный. Если передается константа TIMER_ABSTIME, то получается абсолютный таймер. Если передается нуль, то таймер предполагается относительным.

Структуры для определения времени:

struct timespec{

long tv_sec;

long tv_nsec;

};

struct itimerspec{

struct timespec it_value;

struct timespec it_interval;

};

it_value – однократно используемое значение

it_interval – перегружамое значение

Параметр it_value задает либо интервал времени от настоящего момента до момента срабатывания таймера (в случае относительного таймера), либо собственно время срабатывания (для абсолютного таймера). После того как таймер сработал, он использует для дальнейшей работы значение переменной it_interval. С ее помощью задается относительное время для повторной загрузки таймера Если it_interval = 0, то таймер преобразуется в однократный.

//настройка таймера

timer.it_value.tv_sec = 10; //задержка до запуска таймера 10 сек

timer.it_value.tv_nsec = 10000000; //период срабатывания таймера равный 0.01 сек

timer.it_interval.tv_sec = 0;

timer.it_interval.tv_nsec = 10000000;//время перезагрузки таймера

timer_settime(timer_id, 0, &timer, NULL);//запукс таймера

 

return 0;

}

void gotAPulse()//обработка импульса от таймера

{

clients[0].timeout -= 0.01;

char text[200];

if(clients[0].timeout <= 0){

time_t now;

char buf[27];

time(&now);

sprintf(text,"Message programs - time - %s, ntik = %d \n",ctime_r(&now,buf),g_NTikTimer);

printf(text);

g_NTikTimer = -1;

clients[0].timeout = 1;

}

g_NTikTimer++;//увеличение числа отсчетов таймера

}

 

int main(void)

{

clients[0].in_use = 1;

clients[0].timeout = 1;//выдача сообщения через 1сек

 

 

int rcvid; //Идентификатор отправителя

MessageT msg;

 

//создание канала

g_chid = ChannelCreate(0);

if(g_chid == -1){

печать сообщение об ошибке создания канала;

return -1;

}

//настройка таймера

SetupTimer();

Структура импульса

struct _pulse{

_uint16 type;

_uint16 subtype;

_int8 code;

_uint8 zero[3];

union sigval value;

_int32 scoid;

};

Элементы type и subtype равны нулю. Содержимое элементов code и value определяется отправителем. Элемент code определяет причину, по которой был отправлен импульс (код импульса). Элемент value содержит 32 бита данных, ассоциируемых с импульсом.

//обработка сообщений

while(1){

rcvid = MsgReceive(g_chid, &msg, sizeof(msg), NULL);

 

//Определение того, кто отправлил сообщение

if(rcvid == 0){ //был принят импульс

обработа импульса

switch(код импульса)

если код импульса соответствует коду импульса таймера, то вызвать функцию обработки имульса

}

else{

//обработка обычных сообщений

}

}

return 0;

}

Задание 11

Цель работы — освоение работы с таймером.


Дата добавления: 2015-12-08; просмотров: 68 | Нарушение авторских прав



mybiblioteka.su - 2015-2024 год. (0.012 сек.)