我的流程需要一段时间(可能需要10分钟)才能完成。当我从我的gtk GUI调用它时,窗口会在大约10秒后锁定(变暗并阻止用户操作)。 我想阻止这种情况发生,但我不确定如何发生。我认为多线程就是答案。 我是多线程的新手,所以我正在寻找解决方案。我基本上只是试图阻止GUI锁定,所以我可以使用进度条进行更新,让用户使用取消按钮。
扫描调谐器频率的代码:
int tuner_get_signal (void)
{
..........................
return tuner.signal >> 13;
}
int tuner_check_station (float freq)
{
static int a, b;
static float last;
int signal;
signal = tuner_get_signal ();
if (last == 0.0f)
last = freq;
if ((a + b + signal > 8) && (fabsf (freq - last) > 0.25f)) {
a = b = 0;
last = freq;
return 1;
}
a = b;
b = signal;
return 0;
}
我怀疑我需要为tuner_get_signal()函数
创建线程和扫描功能
typedef struct {
GtkWidget *dialog;
GtkWidget *label;
GtkWidget *progress;
GList *stations;
} FreqScanData;
gboolean scan_cb (gpointer data)
{
static gfloat freq = FREQ_MIN - 4.0f/20;
FreqScanData *fsd = data;
if (freq > 108) {
gtk_widget_destroy (fsd->dialog);
timeout_id = 0;
return FALSE;
}
if (tuner_check_station (freq)) {
gfloat *f;
f = g_malloc (sizeof (gfloat));
*f = freq;
fsd->stations = g_list_append (fsd->stations, f);
}
gtk_progress_bar_set_fraction (GTK_PROGRESS_BAR (fsd->progress),
MAX (0, (freq - 87.5) / (108 - 87.5)));
freq += 1.0/20;
tuner_set_freq (freq);
return TRUE;
}
用以下方式调用:
timeout_id = g_timeout_add (50, (GSourceFunc)scan_cb, (gpointer)&data);
答案 0 :(得分:1)
您的问题的明显解决方案是多线程(计算的背景)。最好也使用Gtk +功能(如您在示例解决方案中所示)。
但是,如果您的程序相当简单,并且您不想让它变得复杂(尤其是结果通信,取消等),您也可以经常中断扫描程序以处理Gtk +事件。请参阅events_pending()的文档: http://www.gtk.org/api/2.6/gtk/gtk-General.html#gtk-events-pending
显然,多线程解决方案的整体性能更好,特别是现在大多数计算机都配备了多个CPU内核。