c - glib 严重错误 (gthread) 和 gtk 微调器未显示

标签 c linux multithreading gtk3 glib

我的发行版 !(Arch Linux) 有一个奇怪的问题。
实际上我正在使用 Arch Linux 和 GNOME 3.16,我已经在 Fedora 上试用了我的软件22 alpha (GNOME 3.16)、Ubuntu 和 Xubuntu 14.10/15.04 但我总是收到相同的错误:
GLib-CRITICAL **: Source ID XXX was not found when trying to remove it
我知道问题出在 g_thread 上,但我无法理解为什么我没有收到 Arch 的警告,而只有其他发行版。
此外,gtk_spinner 小部件仅显示在 Arch 上。在 Fedora 上,它们没有出现,我也没有收到任何错误...

gpointer (*hash_func[NUM_OF_HASH_ENTRY])(gpointer) = {compute_md5, compute_gost94, compute_sha1, compute_sha2, compute_sha3, compute_sha2, compute_sha3, compute_sha2, compute_sha3, compute_whirlpool};

struct hash_vars        
{       
    gint n_bit; //number of hash bit (256, 384, 512)
    gboolean gth_created[NUM_OF_HASH_ENTRY];
    gchar *filename;    
    GHashTable *hash_table;     
    GtkWidget *hash_entry[NUM_OF_HASH_ENTRY]; //md5, gost, sha1, sha256, sha3-256, sha384, sha3_384, sha512, sha3-512, whir     
    GtkWidget *hash_check[NUM_OF_HASH_ENTRY]; //md5, gost, sha1, sha256, sha3-256, sha384, sha3_384, sha512, sha3-512, whir 
    GtkWidget *hash_spinner[NUM_OF_HASH_ENTRY];
    gchar *key[NUM_OF_HASH_ENTRY];
    struct threads_list
    {
        GThread *gth[NUM_OF_HASH_ENTRY];
    } threads;

};  

    struct hash_vars hash_var;
    /* other things */
    for (i = 0; i < NUM_OF_HASH_ENTRY; i++)
    {
            gtk_widget_set_name (GTK_WIDGET (hash_var.hash_check[i]), bt_names[i]);
            hash_var.gth_created[i] = FALSE;
            g_signal_connect (hash_var.hash_check[i], "clicked", G_CALLBACK (create_thread), &hash_var);
    }
    result = gtk_dialog_run (GTK_DIALOG (dialog));
    switch (result)
    {
        case GTK_RESPONSE_REJECT:
            for (i = 0; i < NUM_OF_HASH_ENTRY; i++)
            {
                if(hash_var.gth_created[i])
                    g_thread_join (hash_var.threads.gth[i]);
            }

            g_free (hash_var.filename);
            g_hash_table_destroy (hash_var.hash_table);
            gtk_widget_destroy (dialog);
            break;
    }
}

gpointer
create_thread ( GtkWidget *bt,
                gpointer user_data)
{

    gint i;
    struct hash_vars *hash_var = user_data;
    const gchar *name = gtk_widget_get_name (bt);

    for (i = 0; i < NUM_OF_HASH_ENTRY; i++)
    {
        if (g_strcmp0 (name, bt_names[i]) == 0)
        {      hash_var->gth_created[i] = TRUE;
              hash_var->threads.gth[i] = g_thread_new (NULL, (GThreadFunc)hash_func[i], hash_var);
        }
    }
}

这是哈希函数之一:

gpointer
compute_md5 (gpointer user_data)
{
    struct hash_vars *hash_var = user_data;

    if (!gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (hash_var->hash_check[0])))
    {
        gtk_entry_set_text (GTK_ENTRY (hash_var->hash_entry[0]), "");
        goto fine;
    }
    else if (g_utf8_strlen (gtk_entry_get_text (GTK_ENTRY (hash_var->hash_entry[0])), -1) == 32)
        goto fine;

    gpointer ptr = g_hash_table_lookup (hash_var->hash_table, hash_var->key[0]);
    if (ptr != NULL)
    {
        gtk_entry_set_text (GTK_ENTRY (hash_var->hash_entry[0]), (gchar *)g_hash_table_lookup (hash_var->hash_table, hash_var->key[0]));
        goto fine;
    }

    gtk_spinner_start (GTK_SPINNER (hash_var->hash_spinner[0]));

    /* computing md5 */

    fine:
    gtk_spinner_stop (GTK_SPINNER (hash_var->hash_spinner[0]));
    g_thread_exit(NULL);
}

所以,总而言之,我的问题是:

  1. 我只在发行版 !(Arch Linux) 上收到 GLib-Critical 错误。
  2. gtk_spinner 只出现在 Arch 上

欢迎所有建议:)

最佳答案

"GTK+, however, is not thread safe. You should only use GTK+ and GDK from the thread gtk_init() and gtk_main() were called on. This is usually referred to as the “main thread”."

https://developer.gnome.org/gdk3/stable/gdk3-Threads.html#gdk3-Threads.description

基本上,任何时候你想与 GTK+ 交互,你都应该使用空闲回调来完成。该链接解释了如何操作。

至于为什么它在某些平台上有效而在其他平台上无效,这可能是一个竞争条件。

关于c - glib 严重错误 (gthread) 和 gtk 微调器未显示,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/29539894/

相关文章:

mysql_ping() c api 失败

c++ - `unique_lock`、 `scoped_lock` 和 `lock_guard` 中指定的 mutex_type 的用例是什么?

c++ - std::mutex 和 condition_variable 无法访问类内的私有(private)成员

java - `LockSupport.park()` 可以替换 `Object.wait()` 吗?

将 uint** 转换为 uint

c - scanf ("%c",&x) 和 x=getchar() 有区别吗?

linux - linux 上的 cilk 和 glibc

c - Linux,C : how can I get return value from thread which greate than 4G in a 32bits OS?

C中不同数据类型的连续内存分配?

linux - 变量和双引号