当前位置: 技术问答>linux和unix
GTK多线程编程
来源: 互联网 发布时间:2016-05-10
本文导语: 谁有GTK多线程编程比较经典的例子 覆盖GTK多线程大多数知识的那种例子 画面效果不要求 主要是逻辑方面 谢谢~ | g_thread_init(0); gdk_threads_init(); gtk_init(&argc,&argv); /** * time_update_thread: *...
谁有GTK多线程编程比较经典的例子 覆盖GTK多线程大多数知识的那种例子 画面效果不要求 主要是逻辑方面 谢谢~
|
g_thread_init(0);
gdk_threads_init();
gtk_init(&argc,&argv);
/**
* time_update_thread:
* 这个线程用来显示系统当前的时间,
* 显示格式为 2008-02-24 16:53:00
*/
//获取系统时间
//FIXME:fmt-字符化时间的格式,返回字符型的时间
//get_time("%Y-%m-%d %H:%M:%S");//"%F %An%T"
static const char* get_time(const char *fmt)
{
time_t tmt;
struct tm *tm;
static char text[32];
tmt = time(NULL);
tm = localtime(&tmt);
if(fmt == NULL)//默认的时间格式
fmt = "%Y-%m-%d %H:%M:%S";
strftime(text,sizeof(text),fmt,tm);
return text;
}
static void time_update_thread_func(void)
{
//time_t tmt;
//struct tm *tm;
//char text[32];
const char *text;
pthread_setcancelstate(PTHREAD_CANCEL_ENABLE,NULL);
pthread_setcanceltype(PTHREAD_CANCEL_ASYNCHRONOUS,NULL);
while(1){
//tmt = time(NULL);
//tm = localtime(&tmt);
//strftime(text,sizeof(text),"%Y-%m-%d %H:%M:%S",tm);//"%F %An%T"
text = get_time("%Y-%m-%d %H:%M:%S");
gdk_threads_enter();
gtk_label_set_text(GTK_LABEL(wbus->time),text);
gdk_threads_leave();
sleep(1);
}
return ;
}
void xxxxxx_do_frame_sync(struct frame_t *frame)
{
gdk_threads_enter();
wbuscanner_do_frame(frame);
gdk_display_flush(gdk_display_get_default()); //刷新显示
gdk_threads_leave();
}
gdk_threads_init();
gtk_init(&argc,&argv);
/**
* time_update_thread:
* 这个线程用来显示系统当前的时间,
* 显示格式为 2008-02-24 16:53:00
*/
//获取系统时间
//FIXME:fmt-字符化时间的格式,返回字符型的时间
//get_time("%Y-%m-%d %H:%M:%S");//"%F %An%T"
static const char* get_time(const char *fmt)
{
time_t tmt;
struct tm *tm;
static char text[32];
tmt = time(NULL);
tm = localtime(&tmt);
if(fmt == NULL)//默认的时间格式
fmt = "%Y-%m-%d %H:%M:%S";
strftime(text,sizeof(text),fmt,tm);
return text;
}
static void time_update_thread_func(void)
{
//time_t tmt;
//struct tm *tm;
//char text[32];
const char *text;
pthread_setcancelstate(PTHREAD_CANCEL_ENABLE,NULL);
pthread_setcanceltype(PTHREAD_CANCEL_ASYNCHRONOUS,NULL);
while(1){
//tmt = time(NULL);
//tm = localtime(&tmt);
//strftime(text,sizeof(text),"%Y-%m-%d %H:%M:%S",tm);//"%F %An%T"
text = get_time("%Y-%m-%d %H:%M:%S");
gdk_threads_enter();
gtk_label_set_text(GTK_LABEL(wbus->time),text);
gdk_threads_leave();
sleep(1);
}
return ;
}
void xxxxxx_do_frame_sync(struct frame_t *frame)
{
gdk_threads_enter();
wbuscanner_do_frame(frame);
gdk_display_flush(gdk_display_get_default()); //刷新显示
gdk_threads_leave();
}
|
如果调用次数多的话,gdk_threads_add_idle的效率要慢很多
|
多线程操作UI记得要用gdk_threads_enter,leave来同步, gdk_threads_add_idle增加一个临时运行资源,这个是主线程调用的,并没有创建线程,有些界面操作可以由它来负责
static gboolean idle_update_mach_status(struct reply_t *reply)
{
__update_mach_status(reply);
return FALSE;
}
void wbuscanner_reply_handler(struct reply_t *reply)
{
gdk_threads_add_idle((GSourceFunc)idle_update_mach_status,(gpointer)reply);
}
GTK中的线程能用到的也就这些了,其他的都是pthread的了,比较容易出错的都是同步问题
static gboolean idle_update_mach_status(struct reply_t *reply)
{
__update_mach_status(reply);
return FALSE;
}
void wbuscanner_reply_handler(struct reply_t *reply)
{
gdk_threads_add_idle((GSourceFunc)idle_update_mach_status,(gpointer)reply);
}
GTK中的线程能用到的也就这些了,其他的都是pthread的了,比较容易出错的都是同步问题
|
gtk+的多线程编程不在于滥用gdk_thread_enter()/leave(),在于使用g_idle_add.
网上各种文章都强烈建议,所有对于GUI的操作都在一个线程内完成,其他可能导致阻塞的工作在另外一个线程中。
所以
gdk_threads_enter();
gtk_label_set_text(GTK_LABEL(wbus->time),text);
gdk_threads_leave();
这样的代码应该替换为:
g_idle_add(on_finish, wbus);//子线程中。
gboolean on_finish(gpointer wbus)
{
gtk_label_set_text(GTK_LABEL(wbus->time),text);
return FALSE;
}
参考:
http://gnomerocksmyworld.blogspot.com/2006/05/getting-off-my-lazy-arse.html
网上各种文章都强烈建议,所有对于GUI的操作都在一个线程内完成,其他可能导致阻塞的工作在另外一个线程中。
所以
gdk_threads_enter();
gtk_label_set_text(GTK_LABEL(wbus->time),text);
gdk_threads_leave();
这样的代码应该替换为:
g_idle_add(on_finish, wbus);//子线程中。
gboolean on_finish(gpointer wbus)
{
gtk_label_set_text(GTK_LABEL(wbus->time),text);
return FALSE;
}
参考:
http://gnomerocksmyworld.blogspot.com/2006/05/getting-off-my-lazy-arse.html