Народ в общем такая проблема.
Есть таймер (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;
}
Соответственно в чем может быть проблема ? Кто не успевает? немедленно ли процесс реагирует на сигнал и если этот вариант плох - что можно сделать, чтобы реализовать немедленный вызов некоторой функции (обработки) с заданной частотой с прерыванием других потоков.
ВСЕМ ЗАРАНЕЕ СПАСИБО !