我的发行版 !(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);
}
所以,总而言之,我的问题是:
- 我只在发行版
!(Arch Linux)
上收到 GLib-Critical 错误。 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/