Наши партнеры

UnixForum





Библиотека сайта rus-linux.net

Программирование с использованием gtkmm 3. Функции с временем ожидания, мониторинг операций ввода/вывода и функции для периодов бездействия

Оригинал: Programming with gtkmm 3
Авторы: Murray Cumming, Bernhard Rieder, Jonathon Jongsma, Ole Laursen, Marko Anastasov, Daniel Elstner, Chris Vine, David King, Pedro Ferreira, Kjell Ahlstedt
Дата публикации: 15 Октября 2013 г.
Перевод: А.Панин
Дата перевода: 28 марта 2014 г.

24. Функции с временем ожидания, мониторинг операций ввода/вывода и функции для периодов бездействия

24.1. Функции с временем ожидания

Вы можете задаться вопросом о том, как сделать так, чтобы в приложении на основе gtkmm полезная работа выполнялась в моменты простоя. К счастью, у вас есть несколько вариантов действий. Используя следующие методы, вы можете создать метод с временем ожидания, который будет вызываться через каждые несколько миллисекунд.
sigc::connection Glib::SignalTimeout::connect(const sigc::slot<bool>& slot, unsigned int interval, int priority = Glib::PRIORITY_DEFAULT);
Первым аргументом является слот, который должен использоваться для вызова метода в момент истечения времени ожидания. Вторым аргументом является число миллисекунд между вызовами этого метода. В результате вызова метода вы получите объект идентификации соединения sigc::connection, который может быть использован для деактивации соединения с вызываемым методом с помощью метода disconnect().
my_connection.disconnect();
Другим способом уничтожения соединения с вызываемым методом является использование вашего обработчика сигналов. Это должен быть обработчик типа sigc::slot<bool>. Как вы видите в объявлении метода, ваш обработчик сигналов должен возвращать логическое значение. Объявление вызываемого метода должно выглядеть аналогичным образом:
bool MyCallback() { std::cout << "Hello World!\n" << std::endl; return true; }

Вы можете прекратить использование вызываемого метода, вернув логическое значение false из вашего обработчика сигналов. Следовательно, если вы хотите, чтобы ваш метод вызывался повторно, вы должны возвращать логическое значение true.

Ниже приведен пример использования описанной техники.

Исходный код

Файл: timerexample.h (Для использования совместно с gtkmm 3, а не с gtkmm 2)

Файл: timerexample.cc (Для использования совместно с gtkmm 3, а не с gtkmm 2)

Файл: main.cc (Для использования совместно с gtkmm 3, а не с gtkmm 2)

24.2. Мониторинг операций ввода/вывода

Полезной функцией Glib (одной из библиотек, лежащих в основе gtkmm) является возможность проверки наличия данных при работе с файловым дескриптором. Это особенно полезно при создании сетевых приложений. Для использования этой функции может быть задействован следующий метод:
sigc::connection Glib::SignalInput::connect(const sigc::slot<bool,Glib::IOCondition>& slot,
                                    int fd, Glib::IOCondition condition,
                                    int priority = Glib::PRIORITY_DEFAULT);
Первый аргумент является слотом, который должен быть вызван в момент, когда установленное (с помощью аргумента 3) событие происходит с файловым дескриптором, заданным вами с помощью второго аргумента. Для третьего аргумента может использоваться один или несколько из приведенных ниже флагов (объединение флагов происходит с помощью оператора |):
  • Glib::IO_IN - Ваш метод будет вызван тогда, когда данные будут доступны для чтения из вашего файлового дескриптора.
  • Glib::IO_OUT - Ваш метод будет вызван тогда, когда файловый дескриптор будет готов для записи.
  • Glib::IO_PRI - Ваш метод будет вызван тогда, когда для чтения из файлового дескриптора будут доступны важные данные.
  • Glib::IO_ERR - Ваш метод будет вызван тогда, когда при работе с файловым дескриптором произойдет ошибка.
  • Glib::IO_HUP - Ваш метод будет вызван тогда, когда произойдет разрыв соединения (соединение, обычно создаваемое с использованием каналов или сокетов, будет нарушено).
Возвращаемое значение является объектом идентификации соединения типа sigc::connection, который может использоваться для прекращения мониторинга данного файлового дескриптора путем вызова метода disconnect(). Обработчик сигналов для используемого слота должен быть объявлен следующим образом:
bool input_callback(Glib::IOCondition condition);

причем для аргумента condition используются описанные выше флаги. Как обычно, слот создается с помощью вызова sigc::mem_fun() (для метода класса) или вызова sigc::ptr_fun() (для функции).

Ниже приведен небольшой пример. Для использования этого примера просто запустите скомпилированное приложение из терминала; оно не создает окон. Данное приложение создаст именованный канал с именем testfifo в текущей директории. После запуска откройте еще один терминал и выполните команду "Hello" > testinfo. Приложение будет выводить каждую переданную вами строку до того момента, пока вы не выполните команду echo "Q" > testfifo.

Исходный код

Файл: main.cc (Для использования совместно с gtkmm 3, а не с gtkmm 2)

24.3. Функции для периодов бездействия

В том случае, если вы хотите указать метод, который будет вызываться в течение периодов бездействия приложения, вы можете использовать следующий метод:
sigc::connection  Glib::SignalIdle::connect(const sigc::slot<bool>& slot, int priority = Glib::PRIORITY_DEFAULT_IDLE);
Он принуждает gtkmm к вызову заданного метода в моменты, когда ничего другого не происходит. При этом вы можете задать приоритет операции (меньшие значения соответствуют более высоким приоритетам). Существует два способа удаления обработчика сигналов: вызов метода disconnect() объекта идентификации соединения типа sigc::connection или возврат логического значения false из обработчика сигналов, который должен быть объявлен следующим образом:
bool idleFunc();

Так как данный метод практически полностью аналогичен описанным ранее методам, данных пояснений должно быть вполне достаточно для понимания методики его использования. Однако, ниже приведен небольшой пример:

Исходный код

Файл: idleexample.h (Для использования совместно с gtkmm 3, а не с gtkmm 2)

Файл: idleexample.cc (Для использования совместно с gtkmm 3, а не с gtkmm 2)

Файл: main.cc (Для использования совместно с gtkmm 3, а не с gtkmm 2)

Приведенный пример демонстрирует небольшое различие между методами с временем ожидания и методами периодов бездействия. Если вам требуются методы, которые вызываются периодически и скорость не очень важна, то вам подойдут методы с временем ожидания. Если же вам требуются методы, которые вызываются так часто, как это возможно (для выполнения таких задач, как расчет фрактала в фоновом режиме), вам следует использовать методы для периодов бездействия.

Попробуйте запустить данный пример и повысить нагрузку на систему. Верхний индикатор степени выполнения задачи будет изменять свое значение с такой же скоростью, а нижний - в замедленном темпе.


Следующий раздел : Управление памятью.