GTK не является потокобезопасным, но ориентирован на потоки — его можно использовать из нескольких потоков, гарантируя, что глобальная блокировка используется для защиты вызовов GTK API. Если мне нужно отправить сообщение из рабочего потока в поток графического интерфейса GTK, я просто вызываю gdk_threads_add_idle()
, и указанный обратный вызов будет вызываться в потоке графического интерфейса через некоторое время.
Но как проще всего сделать обратное - вызвать указанный обратный вызов из потока non-GUI
, когда пользователь нажимает кнопку?
G(tk)Object
должен запускаться из приложенияnon-GUI
? Функция, добавленная черезgdk_thread_add_idle()
, срабатывает, когда в очереди событий нет ожидающих событий с более высоким приоритетом ... поэтому через некоторое время будет меняться до вызова функции :) - person another.anon.coward   schedule 16.09.2011code
функциейC
, методом объекта GTK или чем-то еще. Конечно, я могу сделать это вручную, написав стандартный обработчик для события GTK, в этом случае поместив некоторое сообщение в мой собственный запрос и в отдельный поток, я могу использовать некоторый код для ожидания сообщения в очереди и вызвать некоторый обработчик для его обработки. Но это много кода и менее элегантно, чемgdk_threads_add_idle()
:) - person grigoryvp   schedule 16.09.2011GtkWidget
? AFAIK в GTK, если вам нужно обнаружить событие, например, нажатие пользователем кнопки графического интерфейса, это через механизм сигнализации; обратный вызов события запускается, чтобы указать, что конкретное событие произошло (может быть не мгновенным, о чем вы можете быть очень хорошо осведомлены). Таким образом, для нажатия кнопки у вас будет обратный вызов события, в котором вы будете выполнять необходимые операции (блокирующие/неблокирующие). У вас есть вопрос о создании потоков в обработчике событий? Или вы хотите узнать о нажатии кнопки без обработчика событий? - person another.anon.coward   schedule 17.09.2011event callback that indicates that the particular event has occurs
в отдельном потоке без графического интерфейса. Я могу сделать это вручную, отправив сообщение в настраиваемую очередь, которую будет ждать мой поток, но это много кода. Так что, возможно, у GTK есть какой-то встроенный способ распространения сигнала в поток, не связанный с графическим интерфейсом. - person grigoryvp   schedule 17.09.2011event callback
будет вызываться в том же потоке графического интерфейса. Существует возможность создания нового сигнала черезg_signal_new
и передачи их черезg_signal_emit
, который вызовет обработчик сигнала, но я думаю, что он связан сGObject
, и не уверен, что он будет служить вашей цели. Зачем нужна пользовательская очередь? Не может не-GUI ждать условных переменных? Вevent handler
просто сигнализируйте потоку, ожидающему условия.Glib Threads
(как и другие библиотеки потоков) имеют эти возможности - person another.anon.coward   schedule 17.09.2011Glib Threads
в своем потоке без графического интерфейса, используйтеg_cond_wait
для условного ожидания, а при нажатии кнопкиevent callback
on в потоке графического интерфейса просто сигнализируйте условие черезg_cond_signal
, чтобы поток без графического интерфейса доходы. Нет необходимости в пользовательских очередях. Возможно, вы уже знали об этом или могли подумать об этом, но на всякий случай я думаю, что это возможно :) - person another.anon.coward   schedule 17.09.2011gdk_thread_add_idle()
, который позволяет общаться из рабочего потока в поток графического интерфейса.Так что я блуждаю, это что-то так же просто, чтобы общаться из потока графического интерфейса в рабочий поток(и) :). - person grigoryvp   schedule 17.09.2011moveToThread()
в Qt; Я думаю, что это функция / функция, о которой вы упомянули в своем предыдущем комментарии, и ищете для этого альтернативу GTK. Если это так, то, насколько мне известно, я не знаю о такой возможности в GTK, но вGlib
есть возможность пулов потоков, которые могут служить вашей цели. Возможно, вам удастся выполнить вашу задачу в отдельном пуле потоков. - person another.anon.coward   schedule 19.09.2011... reusing already started threads seems like a good idea. And it indeed is, but implementing this can be tedious and error-prone. Therefore GLib provides thread pools for your convenience. An added advantage is, that the threads can be shared between the different subsystems of your program, when they are using GLib.
To create a new thread pool, you use g_thread_pool_new(). It is destroyed by g_thread_pool_free(). If you want to execute a certain task within a thread pool, you call g_thread_pool_push().
HTH - person another.anon.coward   schedule 19.09.2011GLib
, и, к сожалению, не использовалGAsyncQueue
, поэтому я не знал... +1 - person another.anon.coward   schedule 19.09.2011gdk_thread_add_idle()
: мне нужно будет каким-то образом определить идентификаторы сообщений, и это будет БОЛЬШОЙ переключатель внутри потока, который вызовет соответствующий дескриптор функции для сообщения :). Дляgdk_thread_add_idle()
все это бесплатно :(. - person grigoryvp   schedule 24.09.2011