The OpenNET Project / Index page

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

форумы  помощь  поиск  регистрация  майллист  вход/выход  слежка  RSS
"POSIX сигналы. Реализация программного прерывания по таймеру"
Вариант для распечатки  
Пред. тема | След. тема 
Форум Программирование под UNIX (Демоны, Сигналы)
Изначальное сообщение [ Отслеживать ]

"POSIX сигналы. Реализация программного прерывания по таймеру"  +/
Сообщение от xBTx (ok) on 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;
}

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

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

Высказать мнение | Ответить | Правка | Cообщить модератору

Оглавление

Сообщения по теме [Сортировка по времени | RSS]


1. "теряются сигналы "  +/
Сообщение от Вова on 09-Июл-10, 12:26 

>[оверквотинг удален]
>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

Высказать мнение | Ответить | Правка | ^ | Наверх | Cообщить модератору

2. "POSIX сигналы. Реализация программного прерывания по таймеру"  +/
Сообщение от кошечка on 11-Июл-10, 23:18 
>[оверквотинг удален]
>    }
>return 0;
>}
>
>Соответственно в чем может быть проблема ? Кто не успевает? немедленно ли
>процесс реагирует на сигнал и если этот вариант плох - что
>можно сделать, чтобы реализовать немедленный вызов некоторой функции (обработки) с заданной
>частотой с прерыванием других потоков.
>
>ВСЕМ ЗАРАНЕЕ СПАСИБО !

собсно проблема в том что выполнение обработчика сигнала требует
контекста процесса. так что выглядит все таким образом
1) истекает таймер, ядро шлет процессу SIGUSR1
2) _КОГДА ПРОЦЕСС ЗАСКЕДУЛИТСЯ__, управление получит обработчик сигнала

соответственно момент 2 вовсе не обязан настать сразу после истечения таймера.
похоже что вам нужно спустится в ядро

Высказать мнение | Ответить | Правка | ^ | Наверх | Cообщить модератору

3. "POSIX сигналы. Реализация программного прерывания по таймеру"  +/
Сообщение от f00l (ok) on 12-Июл-10, 09:56 
>Соответственно в чем может быть проблема ? Кто не успевает? немедленно ли
>процесс реагирует на сигнал и если этот вариант плох - что
>можно сделать, чтобы реализовать немедленный вызов некоторой функции (обработки) с заданной
>частотой с прерыванием других потоков.
>
>ВСЕМ ЗАРАНЕЕ СПАСИБО !

Если нужна высокая точность , то такими операторами как cout уже не пользуются и по не зависимому секундомеру не замеряют .

Возможный алгоритм, используется функция clock() минимальная информация записывается в память и по прошествии нескольких минут выводится на экран , при выводи на экран есть понятие буферизация , то есть накопление и задержка в отображении .

По умолчанию ядро работает на 100 Hz, то есть планировщик задач переключает процессы и передает им сигналы раз в 1/100 с , здесь требуется скорость в два раза выше .

Либо изменять условия задачи, либо писать модуль ядра .


Высказать мнение | Ответить | Правка | ^ | Наверх | Cообщить модератору

Архив | Удалить

Рекомендовать для помещения в FAQ | Индекс форумов | Темы | Пред. тема | След. тема




Спонсоры:
PostgresPro
Inferno Solutions
Hosting by Hoster.ru
Хостинг:

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