3

特定の GThread に固有のタイムアウト ソースを追加しようとしています。

メイン スレッドでは、GMainContext ( g_main_context_new ) を作成し、タイムアウト ( g_timeout_add ) を追加できます。ただし、 g_thread_createで作成されたスレッドで実行しようとすると、単に機能しません。GSourceFunc が呼び出されることはなく、理由がわかりません。

現時点では、ドキュメントは次のとおりです。

コールバックには少し注意が必要です。GTK+ からのコールバック (シグナル) は、GTK+ ロック内で行われます。ただし、GLib からのコールバック (タイムアウト、IO コールバック、およびアイドル関数) は、GTK+ ロックの外で行われます。したがって、シグナル ハンドラー内では gdk_threads_enter() を呼び出す必要はありませんが、他のタイプのコールバック内では呼び出します。

しかし、私のタイムアウト機能 (テスト用) はコンソールにのみ表示されるため、リソース保護とミューテックスの問題ではないと思います。

スレッド構造は次のとおりです。

メイン スレッド --> GLib メイン コンテキストが明示的に作成されていません

  • キャプチャースレッド

  • プロセス スレッド --> GLib メイン コンテキストとタイムアウト ソースが必要です

  • スレッドを表示

助けていただければ幸いです。

前もって感謝します。

4

1 に答える 1

1

またはを使用しますg_timeout_add()g_source_attach()

g_timeout_add()追加するメイン コンテキストをg_timeout_add_full()指定することはできません。常にデフォルトのメイン コンテキストを使用します。メイン スレッドでデフォルトのメイン コンテキストを使用していない場合は、process thread. あなたは説明でそれについて読むことができます。

GMainContext は単一のスレッドでのみ実行できます

デフォルトのメイン コンテキストは、 を含む多くの関数によって暗黙的に作成されますg_main_context_default()。そのため、メインスレッドで使用していないことを確認してください。

g_source_attach()必要に応じて、独自のメイン コンテキストにタイムアウト ソースを追加するために使用できます。メイン コンテキストを指定するために使用できるタイムアウト関数はありません。だから、自分でやってください。

次のコードは基本的に次と同じです。g_timeout_add_full(G_PRIORITY_DEFAULT, 100, func, l, notify);

#include <glib.h>

void notify(gpointer data)
{
        g_main_loop_quit((GMainLoop *)data);
}

gboolean func(gpointer data)
{
        static gint i = 0;
        g_message("%d", i++);
        return (i < 10) ? TRUE : FALSE;
}

gpointer thread(gpointer data)
{
        GMainContext *c;
        GMainContext *d;
        GMainLoop *l;
        GSource *s;

        c = g_main_context_new();
        d = g_main_context_default();

        g_message("local: %p", c);
        g_message("default: %p", d);

#if 1
        l = g_main_loop_new(c, FALSE);
        s = g_timeout_source_new(100);
        g_source_set_callback(s, func, l, notify);
        g_source_attach(s, c);
        g_source_unref(s);
#else
        l = g_main_loop_new(d, FALSE);
        g_timeout_add_full(G_PRIORITY_DEFAULT, 100, func, l, notify);
#endif

        g_main_loop_run(l);
        g_message("done");

        return NULL;
}

int main(int argc, char *argv[])
{
        GError *error = NULL;
        GThread *t;

        g_thread_init(NULL);
        t = g_thread_create(thread, NULL, TRUE, &error);
        g_thread_join(t);

        return 0;
}
于 2012-08-04T16:13:34.447 に答える