Форум программистов, компьютерный форум CyberForum.ru

С++ под Linux

Войти
Регистрация
Восстановить пароль
 
porshe
52 / 46 / 17
Регистрация: 18.07.2014
Сообщений: 194
#1

Таймер на чтение канала - C++ Linux

04.11.2016, 11:34. Просмотров 399. Ответов 0
Метки нет (Все метки)

Доброго времени суток.
У некого класса есть метод, который читает данные из канала. Проблема в том, что данных в канале может не быть, следовательно, процесс будет приостановлен. Такой расклад дел меня не устраивает (использование O_NONBLOCK врядли возможно) и я хотел бы поставить максимальное время ожидания появления данных в канале.
Соответсвенно, я пытаюсь использовать системный таймер и пытаюсь реализовать следующий алгоритм:
1) блокируем все сигналы кроме SIGALRM
2) устанавливаем обработчик сигнала SIGALRM
3) создаём таймер на заданное время
4) считываем
5) восстанавливаем изначальные разрешённые сигналы, обработчик SIGALRM и таймер

Собственно, это я реализую как-то так:
Кликните здесь для просмотра всего текста

C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
sigset_t last_set, timer_set;
 
void block_signals()
{
    //block all signals without SIGALRM for timer
    if (sigfillset(&timer_set) == -1)
    {
        throw ProcessPipeError(construct_error_message("sigfillset()"));
    }
    if (sigdelset(&timer_set, SIGALRM) == -1) //allow only SIGALRM
    {
        throw ProcessPipeError(construct_error_message("sigdelseg()"));
    }
    if (sigprocmask(SIG_SETMASK, &timer_set, &last_set) == -1)
    {
        throw ProcessPipeError(construct_error_message("sigprocmask()"));
    }
}
 
sig_atomic_t was_timer_end = 0;
void timer_handler(int signo)
{
    was_timer_end = 1;
}
 
struct sigaction timer_action, last_action;
void set_handler()
{
    sigemptyset(&timer_action.sa_mask);
    timer_action.sa_flags = 0;
    timer_action.sa_handler = timer_handler;
 
    if (sigaction(SIGALRM, &timer_action, &last_action) == -1)
    {
        throw ProcessPipeError(construct_error_message("sigaction()"));
    }
}
 
itimerval read_timer, last_timer;
void set_timer(long sec, long usec)
{
    timerclear(&read_timer.it_interval);
    timerclear(&read_timer.it_value);
 
    read_timer.it_value.tv_sec = sec;
    read_timer.it_value.tv_usec = usec;
 
    if (setitimer(ITIMER_REAL, &read_timer, &last_timer) == -1)
    {
        throw ProcessPipeError(construct_error_message("setitimer()"));
    }
}
 
void restore_timer()
{
    setitimer(ITIMER_REAL, &last_timer, nullptr);
}
 
void restore_handler()
{
    sigaction(SIGALRM, &last_action, nullptr);
}
 
void restore_signals()
{
    sigprocmask(SIG_SETMASK, &last_set, nullptr);
}
 
 
int ProcessPipe::receive(void *data, int len, long sec, long usec)
{
    block_signals();
    set_handler();
    was_timer_end = 0;
    set_timer(sec, usec);
    int read_len = read(_infd[0], data, len);
    restore_timer();
    restore_handler();
    restore_signals();
 
    if (was_timer_end)
    {
        return -1;
    }
 
    if (read_len < 0)
    {
        throw ProcessPipeError(construct_error_message("read()"));
    }
 
    return read_len;
}


И на первый взгляд этот код работает, однако если во время ожидания кинуть сигнал SIGINT то программа упадёт. Но почему? Я же игнорирую все сигналы кроме SIGALRM, или нет?
Similar
Эксперт
41792 / 34177 / 6122
Регистрация: 12.04.2006
Сообщений: 57,940
04.11.2016, 11:34     Таймер на чтение канала
Посмотрите здесь:

Таймер на C++ - C++ Linux
Всем доброго времени суток. Подскажите, как сделать таймер под программу на linux ? Надо, чтобы раз в два часа таймер слал запрос на...

Таймер в Linux - только по-секундный? - C++ Linux
Есть функция timer(long*), с помощью неё можно мерять интервал времени в секундах. В ДОС и Windows есть аналогичная функция, но меряет...

Таймер с периодом меньше секунды - C++ Linux
нужно к примеру выполнять что-то 5 раз в секунду. #define PRETIME 15*60 /* 15 минут */ как я понимаю в секундах. можно ли...

Как реализовать простой таймер? - C++ Linux
простая программка 2 кнопки. старт и стоп. когда нажимаеш кнопку старт то каждую секунду должно выполняться какое-то действие, например...

C++ и таймер, вызвать функцию каждые пару секунд - C++ Linux
Народ, помогите. Пользую связку gtkmm и GLADE и хочу чтоб при нажатии на кнопку, скажем, функция &quot;Х&quot; запускалась на выполнение по таймеру....

Таймер для замера времени выполнения операции на основе hpet - C++ Linux
Здравствуйте. Собственно, необходимо вычислить временной интервал выполнения некоторой функции. Основное требование - максимальная...

Запись и чтение чисел из програмного канала pipe - C (СИ)
Нужно создать программный канал, записать в него 3 действительных числа а затем считать. С созданием проблем нет, но как записывать в канал...

Дан номер телевизионного канала (от 1 до 5).Вывести на экран наиболее популярные программы заданного канала - C++
Дан номер телевизионного канала (от 1 до 5).Вывести на экран наиболее популярные программы заданного канала.

Таймер прерывает чтение из fifo - C Linux
Здравствуйте. Столкнулся с такой проблемой. Есть программа сервера, управление которым производится посредством именованного канала. Т.е....

ширина канала - Сети
Скажите какую ширину канала надо взять у провайдера чтоби подключить 1000 человек. на скорости от 10 до 100 мб.сек.

2 Интернет канала - Сетевое оборудование
Доброго времени суток! Возникла следующая проблема: Есть 2 Интернет-канала: более быстрый A и более медленный B. Есть сервер, к которому...

Скорость канала - Сети
Добрый день Господа. Не знал в какую ветку поместить данную тему, поэтому она здесь. У меня скорость интернет канала 5мб с...


Искать еще темы с ответами

Или воспользуйтесь поиском по форуму:
После регистрации реклама в сообщениях будет скрыта и будут доступны все возможности форума.
Ответ Создать тему
Опции темы

КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin® Version 3.8.9
Copyright ©2000 - 2017, vBulletin Solutions, Inc.
Рейтинг@Mail.ru