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

С++ под Linux

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

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

04.11.2016, 11:34. Просмотров 410. Ответов 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, или нет?
0
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
Similar
Эксперт
41792 / 34177 / 6122
Регистрация: 12.04.2006
Сообщений: 57,940
04.11.2016, 11:34
Здравствуйте! Я подобрал для вас темы с ответами на вопрос Таймер на чтение канала (C++ Linux):

Деление Wav-файла на два канала - C++
Реализовать функцию разделяющую входной wav файл на каналы (на два выходных файла) с возможностью уменьшения амплитуд любого из каналов. ...

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

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

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

Таймер должен через время положить файл на БД. [Таймер] - Apache, htaccess
Мне нужен таймер, а я не знаю как его делать именно, чтоб в конкретное время он сохранял информацию в файл. Чтобы он в конкретный период...

Таймер похожий на таймер в delphi - C++ WinAPI
Добрый всем)В общем хочу создать класс таймера похожий на класс таймера на delphi.Суть в том,что я хочу включать и выключать таймер за счет...

0
MoreAnswers
Эксперт
37091 / 29110 / 5898
Регистрация: 17.06.2006
Сообщений: 43,301
04.11.2016, 11:34
Привет! Вот еще темы с ответами:

объедение 2 канала в 1 - Сетевое оборудование
Есть такая проблема. Мой провайдер поставляет интернет, 28 мб максимум. Мне нужно хотя бы 50 мб. Если мне провести в квартиру 2 кабеля по...

Состояние канала - Visual C++
Пипл! Поздскажите, пожалуйста, как со стороны сервера канала Pipe узнать, подключен ли к его каналу кто нибудь или нет??? Пробовал: ...

Обрыв канала - Программирование Android
Здравствуйте! Опять столкнулся с очередной проблемой, которую не могу решить. Дело в том, что при написании программы я использовал...

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


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

Или воспользуйтесь поиском по форуму:
1
Ответ Создать тему
Опции темы

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