Почему gtkmm иногда автоматически создает второй поток?

Если я скомпилирую и запущу код как есть, процесс будет работать с 1 потоком. Если я раскомментирую закомментированный раздел, а затем скомпилирую и запущу его, он будет работать с двумя потоками.

Я компилирую код с помощью этой команды: g++ pkg-config gtkmm-2.4 --cflags --libs test.cpp

Когда программа запущена, я могу проверить, сколько потоков создано с помощью: ps -mC a.out

Если я посмотрю на второй поток в ddd, я увижу, что он работает g_main_loop_run. Меня это смущает:

  • Какова цель этой темы?
  • Почему добавление кнопки на панель инструментов создает новую тему?
  • Я думал, что g_main_loop_run() должен выполняться только в одном потоке (если только вы не используете макросы GDK_THREADS_ENTER/GDK_THREADS_LEAVE). Поскольку я запускаю Gtk::Main::Run() в своем основном потоке, нарушаю ли я правила?

Заранее благодарю за любую помощь. Это сводит меня с ума.

#include <gtkmm.h>

bool OnDeleteEvent(GdkEventAny* PtrGdkEventAny)
{
    Gtk::Main::quit();
    return(true);
}

void OnExecuteButtonClicked()
{
}

int main(int argc, char *argv[])
{
    new Gtk::Main(0, NULL);

    Gtk::Window *ptrWindow = new Gtk::Window;
    ptrWindow->signal_delete_event().connect(sigc::ptr_fun(&OnDeleteEvent));

    /*
    Gtk::Toolbar *ptrToolBar = manage(new Gtk::Toolbar);
    Gtk::ToolButton *ptrToolButton;

    ptrToolButton = manage( new Gtk::ToolButton(Gtk::Stock::EXECUTE));
    ptrToolBar->append(*ptrToolButton, sigc::ptr_fun(&OnExecuteButtonClicked));

    ptrWindow->add(*ptrToolBar);
    */

    ptrWindow->show_all();
    Gtk::Main::run();

    return (0);
}

person Vern    schedule 27.01.2014    source источник
comment
Я думал, что g_main_loop_run() должен выполняться только в одном потоке (если вы не используете макросы GDK_THREADS_ENTER/GDK_THREADS_LEAVE) — это предложение на самом деле не имеет смысла. Конечно, основной цикл и обратные вызовы выполняются в одном потоке, но нет гарантии, что за кулисами используется только один поток.   -  person Jussi Kukkonen    schedule 28.01.2014
comment
Хорошо, поэтому я думаю, что ответ таков: не беспокойтесь об этой другой теме, она не влияет на вас. Я провел небольшой эксперимент, чтобы убедиться, что обратные вызовы никогда не вызываются с помощью ThreadId другого потока, а это не так. Это было моей главной заботой. Я предполагаю, что Gtk, вероятно, использует другой поток для повышения производительности. Спасибо за ответ.   -  person Vern    schedule 28.01.2014


Ответы (1)


Иногда GThread создаются, когда вы используете функции, основанные на асинхронном поведении. Они обычно создают GTask внутри (с g_task_run_in_thread и друзьями) и запускают синхронную версию в отдельном потоке (за исключением тех, которые изначально асинхронны или асинхронны, они обычно не порождают другой поток). Обычно это IO (например, GtkBuilder), Socket и IPC (dbus), так что в основном это glib.

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

Так что в вашем случае я могу думать только о двух вещах, которые могут вызвать это: изображение Stock, которое загружается с вашего локального диска, или информация о стиле вашей темы.

person drahnr    schedule 29.01.2014