Народ в общем такая проблема.
Есть таймер (200Гц) , выдающий сигналы SIGUSR1. Есть процесс состоящий из двух потоков - каждый
просто бесконечно инкрементирует и сбрасывает счетчик - тем самым создают полную загрузку процессора.
Необходимо реализовать немедленную реакцию на сигналы таймера (фактически вне зависимости от приоритетов и операций выполняемых потоками)
На первый взгляд самое просто повесить обработчик сигналов с помощью sigaction(). Что я и пытаюсь делать. Проверка "немедленной реакции " осуществляется банально - внутри обработчика инкрементирую счетчик по достижению числа кратного 200 инкрементирую 2ой счетчик и вывожу на экран. Таким образом выводимые значения должны просто соответствовать значению секундомера (в сек).Но в реальности происходит очень сильное отставание (секунд 15-20 за минуту). Вот реализация:#include <cstdio>
#include <signal.h>
#include <iostream>
#include <unistd.h>
#include <pthread.h>
#include "../libraries/timer_200.h"//таймер 200Гцusing namespace std;
void * thread_func (void * arg)
{
int j=0;
while (1)
{
j++;
if (j>300) j=0;
}
}int init_thread ( int priority)
{
int i=0;
pthread_t pid;
pthread_attr_t attr;struct sched_param param;
pthread_attr_init ( &(attr) );
if (priority >= 0 )
{
pthread_attr_setinheritsched(&(attr), PTHREAD_EXPLICIT_SCHED);}
pthread_create ( &(pid), &(attr), thread_func, NULL ); //Thread creation
if (pid < 0)
{
printf ("\nCan't creat thread !!!\n");
}
else
{
if (priority >=0)
{param.sched_priority = priority;
sched_setparam ( pid, ¶m );}
}
}static void sighandler(int sig, siginfo_t * , void * )
{
static int time=0;
static unsigned long int counter=0;
counter++;
if (counter > 4000000) counter =1;
if (counter % 200 == 0)
{
time++;
cout<<"The handler works !!! Time="<<time<<endl;
}
}void init_handler()
{
struct sigaction mysig;
mysig.sa_sigaction = sighandler;
mysig.sa_flags = SA_SIGINFO;
sigaction(SIGUSR1, &mysig, NULL);
}
int main()
{
unsigned long int j =0;
int i=0;
InitMainClk();//Timer init
init_handler();
init_thread(-1);//Разблокируем сигнал
sigprocmask (SIG_UNBLOCK, &set, NULL);while (1)
{
i++;
if (i % 200 == 0)
{
i=0;
j++;
if (j > 1000000) j=1;
}}
return 0;
}Соответственно в чем может быть проблема ? Кто не успевает? немедленно ли процесс реагирует на сигнал и если этот вариант плох - что можно сделать, чтобы реализовать немедленный вызов некоторой функции (обработки) с заданной частотой с прерыванием других потоков.
ВСЕМ ЗАРАНЕЕ СПАСИБО !
>[оверквотинг удален]
>static unsigned long int counter=0;
> counter++;
> if (counter > 4000000) counter =1;
> if (counter % 200 == 0)
> {
> time++;
>
>
> cout<<"The handler works !!! Time="<<time<<endl;
> }необходимо блокировать сигналы в обработчике, они теряются - http://www1.lib.ru/CTOTOR/book.txt_with-big-pictures.html
>[оверквотинг удален]
> }
>return 0;
>}
>
>Соответственно в чем может быть проблема ? Кто не успевает? немедленно ли
>процесс реагирует на сигнал и если этот вариант плох - что
>можно сделать, чтобы реализовать немедленный вызов некоторой функции (обработки) с заданной
>частотой с прерыванием других потоков.
>
>ВСЕМ ЗАРАНЕЕ СПАСИБО !собсно проблема в том что выполнение обработчика сигнала требует
контекста процесса. так что выглядит все таким образом
1) истекает таймер, ядро шлет процессу SIGUSR1
2) _КОГДА ПРОЦЕСС ЗАСКЕДУЛИТСЯ__, управление получит обработчик сигналасоответственно момент 2 вовсе не обязан настать сразу после истечения таймера.
похоже что вам нужно спустится в ядро
>Соответственно в чем может быть проблема ? Кто не успевает? немедленно ли
>процесс реагирует на сигнал и если этот вариант плох - что
>можно сделать, чтобы реализовать немедленный вызов некоторой функции (обработки) с заданной
>частотой с прерыванием других потоков.
>
>ВСЕМ ЗАРАНЕЕ СПАСИБО !Если нужна высокая точность , то такими операторами как cout уже не пользуются и по не зависимому секундомеру не замеряют .
Возможный алгоритм, используется функция clock() минимальная информация записывается в память и по прошествии нескольких минут выводится на экран , при выводи на экран есть понятие буферизация , то есть накопление и задержка в отображении .
По умолчанию ядро работает на 100 Hz, то есть планировщик задач переключает процессы и передает им сигналы раз в 1/100 с , здесь требуется скорость в два раза выше .Либо изменять условия задачи, либо писать модуль ядра .