Есть ли способ иметь точные временные события в GTK / GLib?

#c #events #timer #gtk #glib

#c #Мероприятия #таймер #gtk #glib

Вопрос:

Я хочу иметь функцию, которая выполнялась бы каждые N миллисекунд, и я хочу, чтобы она выполнялась точно (относительно, мне не нужна точность атомных часов). Из того, что я вижу, в руководстве GLib говорится, что g_timeout_add() это не гарантирует точность и может быть отложено из-за других событий.

Есть ли какой-либо другой способ иметь точные временные события с GTK / GLib? Я бы предпочел не использовать код, зависящий от платформы, поскольку я хочу, чтобы моя программа работала как в Windows, так и в Linux с как можно меньшим количеством изменений кода, связанных с платформой.

Комментарии:

1. Вы проверяли g_timeout_add() , чтобы увидеть, насколько это неточно? Вы также можете создать источник таймера, используя g_timeout_source_new() и увеличивая его приоритет с помощью g_source_set_priority() , что должно придать ему больший приоритет планирования в основном цикле по сравнению с другими источниками. Это должно уменьшить дрожание.

Ответ №1:

Насколько точны «не атомарные часы»? В конце концов, точность синхронизации будет ограничена такими факторами, как поведение платформы при переключении контекста. Если вы не используете клиентские ядра или специализированное оборудование, вы, возможно, мало что сможете с этим поделать.

g_timeout_add() вдвойне проблематично, потому что его работа связана с механизмом обработки событий GTK, который никогда не был разработан для точности.

В конце концов, ваши лучшие ставки могут быть либо

  1. Используйте обычный таймер на основе сигнала (например, из setitimer ) или
  2. Создайте новый поток и просто usleep() фиксированное время между действиями.

Оба эти подхода проблематичны в GTK, потому что сложно обновить пользовательский интерфейс вне основного контекстного потока GTK. Обычно требуется довольно сложная блокировка и взаимодействие между потоками.

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

Ответ №2:

Без дополнительных подробностей g_usleep , вероятно, было бы вашим лучшим выбором, но имейте в виду, что это блокирует текущий поток, поэтому, если вы хотите, чтобы другие задачи выполнялись параллельно, вам нужно создать новый поток для его запуска.