The OpenNET Project / Index page

[ новости /+++ | форум | теги | ]



Индекс форумов
Составление сообщения

Исходное сообщение
"POSIX сигналы. Реализация программного прерывания по таймеру"
Отправлено xBTx, 08-Июл-10 19:18 
Народ в общем такая проблема.
Есть таймер (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;
}

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

ВСЕМ ЗАРАНЕЕ СПАСИБО !

 

Ваше сообщение
Имя*:
EMail:
Для отправки новых сообщений в текущей нити на email укажите знак ! перед адресом, например, !user@host.ru (!! - не показывать email).
Более тонкая настройка отправки ответов производится в профиле зарегистрированного участника форума.
Заголовок*:
Сообщение*:
 
При общении не допускается: неуважительное отношение к собеседнику, хамство, унизительное обращение, ненормативная лексика, переход на личности, агрессивное поведение, обесценивание собеседника, провоцирование флейма голословными и заведомо ложными заявлениями. Не отвечайте на сообщения, явно нарушающие правила - удаляются не только сами нарушения, но и все ответы на них. Лог модерирования.



Партнёры:
PostgresPro
Inferno Solutions
Hosting by Hoster.ru
Хостинг:

Закладки на сайте
Проследить за страницей
Created 1996-2024 by Maxim Chirkov
Добавить, Поддержать, Вебмастеру