我发现!(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 attempting to remove it
我知道问题出在g_thread
但是我无法理解为什么我没有收到Arch的警告,只能用其他发行版收到警告。
此外,{{1小部件仅在Arch上显示。在Fedora上他们没有出现,我没有收到任何错误......
gtk_spinner
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);
}
!(Arch Linux)
仅在Arch 欢迎所有建议:)
答案 0 :(得分:0)
“然而,GTK +不是线程安全的。你应该只使用线程gtk_init()中的GTK +和GDK,并且调用gtk_main()。这通常被称为”主线程“。”
- https://developer.gnome.org/gdk3/stable/gdk3-Threads.html#gdk3-Threads.description
基本上,只要您想与GTK +进行交互,就应该使用空闲回调来实现。该链接解释了如何。
至于为什么它适用于某些平台而不适用于其他平台,这可能是一种竞争条件。