C попытка отличить общий указатель - PullRequest
0 голосов
/ 25 июня 2010

Я пытался позвонить,

g_io_scheduler_push_job(job_func, &param, NULL, G_PRIORITY_HIGH, generator_cancellable);

В моем C/gtk+ приложении для запуска job_func() в другом потоке, чем основная программа.Но при вызове этой функции произошла ошибка segfault, и отладчик сказал, что: ** пользовательские данные пытаются различить общий указатель **

Код job_func():

gboolean job_func(GIOSchedulerJob *job, GCancellable *cancellable, gpointer user_data)
{       
    JobParam* job_param = (JobParam*)user_data; 
    build(NULL, job_param->mw);
    return TRUE;
}

Где JobParam,

typedef struct _JobParam
{
  GtkWidget* widget;
  MainWin*   mw;
}JobParam;

Где MainWin,

typedef struct _MainWin
{
    GtkWindow parent;
    GtkWidget* scroll;
    GtkWidget* box;
    GtkUIManager *uimanager;
} MainWin;

И build,

void build(GtkWidget* widget, MainWin* mw)
{
    gtk_list_store_clear(mw->model);
}

Как это исправить?

Спасибо.

Ответы [ 2 ]

2 голосов
/ 27 июня 2010

Вы возитесь с виджетами (и связанными с ними вещами) из основного потока, НЕ ДЕЛАЙТЕ ЭТОГО.

Функции GTK не являются потокобезопасными, если в документации не указано иное, вы не можете манипулировать виджетами (и я вполне уверен, реализации GtkTreeModel) в любом потоке, кроме того, в котором выполняется основной цикл.В основном просто нет.Я думаю, что вы могли бы сделать это, если И ТОЛЬКО ЕСЛИ в GtkListStore нет GtkTreeView, прикрепленного к нему.(и если вы делаете много изменений, то в любом случае рекомендуется сначала отключить его, сохранить перерисовки и множество бесполезных событий)

РЕДАКТИРОВАТЬ: причина, по которой я упоминаю отключение TreeView от ListStore, заключается в том, что я ожидаючто вы пытаетесь сделать gtk_list_store_clear() в отдельном потоке, потому что это занимает слишком много времени, это распространенная проблема, каждый раз, когда вы собираетесь добавить / удалить большое количество строк в / из TreeModel, вы должны сначала сделать gtk_tree_view_set_model(treeview, NULL);

1 голос
/ 25 июня 2010

Не видя полного кода, сложно определить, что происходит.Я предполагаю, что param распределяется в стеке в зависимости от способа его передачи, поэтому адрес недействителен, когда ваш job_func на самом деле называется недействительным и разыменовывает мусор.

Попробуйте выделить ваш параметр с помощью mallocи затем освобождая это.Вы можете передать GDestroyNotify , который вы можете бесплатно позвонить в течение.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...