下面是一个小程序,其实是一个简单的事件触发模型:
#include <glib.h>
#include <stdio.h>
#include <strings.h>
GMainLoop *loop;
gboolean callback(GIOChannel *channel)
{
gchar *str;
gsize len;
/*stdin*/
g_io_channel_read_line(channel, &str, &len, NULL, NULL);
while(len>0 && (str[len-1] == '\r' || str[len-1] == '\n'))
str[--len]='\0';
for(;len;len--)
g_print("%c",str[len-1]);
g_print("\n");
if(strcasecmp(str, "q") == 0) {
g_main_loop_quit(loop);
}
g_free(str);
}
void add_source(GMainContext *context)//???souece channel context
{
GIOChannel *channel;
GSource *source;
//stdiio?fd1
channel = g_io_channel_unix_new(1);
source = g_io_create_watch(channel, G_IO_IN);
g_io_channel_unref(channel);
g_source_set_callback(source, (GSourceFunc)callback, channel, NULL);//
//GSourceGMainContext
g_source_attach(source, context);
g_source_unref(source);
}
int main(int argc, char *argv[])
{
GMainContext *context;
// if(g_thread_supported() == 0)
// g_thread_init(NULL);
context = g_main_context_new();
add_source(context);
loop = g_main_loop_new(context, FALSE);
g_print("input string('q' to quit)\n");
g_main_loop_run(loop);//
g_main_loop_unref(loop);
g_main_context_unref(context);
return 0;
}
callback函数在 g_main_loop_run()里面被调用。具体的调用栈是这样的:
#0 callback (channel=0x804c100) at test50.c:12
#1 0xb7f2e0b5 in g_io_unix_dispatch (source=source@entry=0x804c148,
callback=0x80488ed <callback>, user_data=0x804c100) at giounix.c:165
#2 0xb7ee8197 in g_main_dispatch (context=0x804bf00, context@entry=0x804c148)
at gmain.c:3122
#3 g_main_context_dispatch (context=context@entry=0x804bf00) at gmain.c:3737
#4 0xb7ee8558 in g_main_context_iterate (context=0x804bf00,
block=block@entry=1, dispatch=dispatch@entry=1, self=<optimized out>)
at gmain.c:3808
#5 0xb7ee8853 in g_main_loop_run (loop=0x804c1d0) at gmain.c:4002
#6 0x08048aac in main (argc=1, argv=0xbffff084) at test50.c:49
可以看到, callback函数只有在 g_main_loop_run开始后才可能被触发执行。