在GTK + 2.0应用程序中使用pthread的安全性 [英] Safety of using pthreads in Gtk+2.0 application

查看:225
本文介绍了在GTK + 2.0应用程序中使用pthread的安全性的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个简单的多线程GTK + 2.0应用程序,它从多个源(麦克风,摄像头,温度传感器),并显示数据从这些为图像在屏幕上(摄像头边框争夺,麦克风数据重新presented作为示波器采集数据呈现,文本等)。

I have a simple multithreaded Gtk+2.0 application that acquires data from multiple sources (microphone, webcam, temperature sensor), and displays data from these as images on screen (webcam frame grabs, microphone data represented as oscilloscope renders, text, etc).

这是从GTK的手动和各种文章我的理解,只有主处理线程应该使用任何基于GTK功能影响UI /电话。但是,的main()入口点关于进入主循环块(),直到我关闭UI。随着映射到之类的东西,当我点击我的UI按钮或滑块事件处理程序的例外,它似乎敞开我唯一的选择就是产卵数的pthread S和让他们做数据的定期抽样和屏幕更新信息在UI中。

It's to my understanding from the Gtk manual and various articles that only the main processing thread should use any Gtk functions/calls that affect the UI. However, the main() entry point blocks on gtk_main() until I close the UI. With the exception of event handlers that are mapped to things like when I click on a button or slider in my UI, it seems the only option left open to me is to spawn a few pthreads and have them do the periodic sampling of data and updating information on-screen in the UI.

我是从做一些MFC GUI开发还很远背部施加类似的原则记住:只有一个特定的线程应更新UI元素。我如何用GTK + 2.0完成这在C?

I remember from doing some MFC GUI development a long ways back that a similar principle applied: only a single specific thread should be updating the UI elements. How do I accomplish this in C with Gtk+2.0?

感谢您。

推荐答案

据该的文档,主甚至循环可以从不同的线程接受来源:

According to the documentation, the main even loop can accept sources from different threads:

一个GMainContext只能在一个线程中运行,但消息人士能
  从其他线程添加到它并删除它。

A GMainContext can only be running in a single thread, but sources can be added to it and removed from it from other threads.

所以,你可以从你的工作线程通过注入在UI线程的code:

So you can inject the code in the UI thread from your working thread by:


  1. 创建一个 GSource (例如,通过使用<一个href=\"https://developer.gnome.org/glib/stable/glib-The-Main-Event-Loop.html#g-idle-source-new\"><$c$c>g_idle_source_new);

  2. 添加code要与<一个被执行href=\"https://developer.gnome.org/glib/stable/glib-The-Main-Event-Loop.html#g-source-set-callback\"><$c$c>g-source-set-callback;

  3. 它<一个连接到UI线程上下文href=\"https://developer.gnome.org/glib/stable/glib-The-Main-Event-Loop.html#g-source-attach\"><$c$c>g_source_attach().

  1. creating a GSource (e.g., by using g_idle_source_new);
  2. adding the code you want to be executed with g-source-set-callback;
  3. attaching it to the UI thread context with g_source_attach().

下面是GTK + 2和GLib的一个示例程序> = 2.32:

Here is a sample program for GTK+2 and GLib >= 2.32:

#include <gtk/gtk.h>

#define N_THREADS    100
#define N_ITERATIONS 100

GtkWidget *bar;
GMainContext *context;

static gboolean
update_progress_bar(gpointer user_data)
{
    gtk_progress_bar_set_fraction(GTK_PROGRESS_BAR(bar),
                                  g_random_double_range(0, 1));
    return G_SOURCE_REMOVE;
}


static gpointer
thread_func(gpointer user_data)
{
    int n_thread = GPOINTER_TO_INT(user_data);
    int n;
    GSource *source;

    g_print("Starting thread %d\n", n_thread);

    for (n = 0; n < N_ITERATIONS; ++n) {
        /* If you want to see anything you should add a delay
         * to let the main loop update the UI, e.g.:
         * g_usleep(g_random_int_range(1234, 567890));
         */
        source = g_idle_source_new();
        g_source_set_callback(source, update_progress_bar, NULL, NULL);
        g_source_attach(source, context);
        g_source_unref(source);
    }

    g_print("Ending thread %d\n", n_thread);
    return NULL;
}


gint
main(gint argc, gchar *argv[])
{
    GtkWidget *window;
    GThread *thread[N_THREADS];
    int n;

    gtk_init(&argc, &argv);

    window = gtk_window_new(GTK_WINDOW_TOPLEVEL);
    g_signal_connect(window, "destroy", G_CALLBACK(gtk_main_quit), NULL);

    bar = gtk_progress_bar_new();
    gtk_container_add(GTK_CONTAINER(window), bar);

    context = g_main_context_default();

    for (n = 0; n < N_THREADS; ++n)
        thread[n] = g_thread_new(NULL, thread_func, GINT_TO_POINTER(n));

    gtk_widget_show_all(window);
    gtk_main();

    for (n = 0; n < N_THREADS; ++n)
        g_thread_join(thread[n]);

    return 0;
}

这篇关于在GTK + 2.0应用程序中使用pthread的安全性的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆