【发布时间】:2018-05-06 15:44:39
【问题描述】:
我正在用 C 语言开发一个程序,它使用 GTK+3 并遵循 - 或多或少 - MVC 架构:
- 模型每 20 毫秒通过调用 model_update 更新一次(它不调用 GTK 函数);
- GUI 通过读取模型变量每 50 毫秒调用一次 gui_update 进行更新。
我的问题是 GUI 在随机运行时间后冻结,可能是 20 分钟或超过 1 小时,我不知道为什么。也许我应该知道一些关于 GTK 的事情?
注意: 使用互斥锁可以保护对模型变量的访问。
非常感谢您的帮助!!
#include <signal.h>
#include <gtk/gtk.h>
#include <stdlib.h>
#include <sys/time.h>
#include <sys/prctl.h>
void *
thread_gui(void* data)
{
g_timeout_add(50, handler_timer_gui_update, NULL); // updates the GUI each 50ms
gtk_main();
pthread_exit(NULL);
}
gint
handler_timer_gui_update(gpointer data)
{
gui_update();
// gui_update reads the model and updates GUI by using
// gtk_label_set_text, gtk_spin_button_set_value, cairo_paint
return TRUE;
}
void
launch_periodical_call_updating_model( )
{
signal( SIGRTMIN + 1, model_update );
timer_t timer;
struct sigevent event;
event.sigev_notify = SIGEV_SIGNAL;
event.sigev_signo = SIGRTMIN + 1;
event.sigev_value.sival_ptr = &timer;
timer_create(CLOCK_REALTIME, &event, &timer);
struct itimerspec spec;
spec.it_value.tv_nsec = 20 * 1000000; // updates the model each 20 ms
spec.it_value.tv_sec = 0;
spec.it_interval = spec.it_value;
timer_settime( timerModel, 0, &spec, NULL);
}
int
main( int argc, char *argv[] )
{
pthread_t pthread_gui;
init_model( ); // init model variables
launch_periodical_call_updating_model( );
// signal capture to exit
signal( SIGINT, ctrlc_handler );
signal( SIGTERM, ctrlc_handler );
// GUI
g_thread_init(NULL);
gdk_threads_init();
gdk_threads_enter();
gtk_init( &argc, &argv );
create_gui ( ); // building GTK Window with widgets
pthread_create(&pthread_gui, NULL, thread_gui, NULL);
gdk_threads_leave();
// Leaving the program
pthread_join( pthread_gui, NULL );
stop_model( ); //It stops to update the model and releases memory
return 0;
}
void
ctrlc_handler( int sig )
{
gtk_main_quit();
}
【问题讨论】:
-
尝试在信号处理程序中获取互斥锁是一个非常糟糕的主意:(