基于glib的单线程多事件源处理

传统实现程序命令行的输入一般使用scanf或者getchar系统调用,这样,要求程序实现时要使用一个独立的线程检测用户的输入,这样就涉及到多线程编程的一系列问题。glib的mainloop机制可以提供单线程多事件源的注入,只要我们将用户的输入转换成GSource,就可以实现一种单线程的既可以响应用户输入,同时又能在输入的间隙处理其它事件的类并发模型。
1、基本概念
1.1 GMainContext
1.2 GMainLoop
1.3 GSource
1.4 Poll机制
1.5 File Descriptor
2、实现
2.1 创建一个GMainLoop
loop = g_main_loop_new (NULL, FALSE);
参数说明:
NULL指的是GMainLoop基于的GMainContext,NULL参数表示该mainloop基于glib的default context。
2.2 创建一个GSource
2.2.1 为GSource提供一个回调函数结构体
static gboolean prepare( GSource * source, gint * timeout_ )
{
    * timeout_  =   -1;


    return FALSE;
}


static gboolean check( GSource * source )
{
  gboolean _result    =   FALSE;




if( fd.revents == POLLIN )
{
_result =   TRUE;
}


return _result;
}




static gboolean dispatch( GSource * source, GSourceFunc callback, gpointer user_data )
{
    gchar _cmd[100]  =   {0};


    read( 0, _cmd, sizeof( _cmd ));


    switch( _cmd[0] )
    {
    case 'h':
        printUsage();
        break;
    case 'p':
        break;
    case 'x':
        g_main_loop_quit (loop);
        break;
    case '>':
        break;
    case '<':
        break;
    default:
        break;
    }




printf( ">" );
fflush( stdout );


return G_SOURCE_CONTINUE;
}
static GSourceFuncs funcs   =
{
    .prepare    =   prepare,
    .check      =   check,
    .dispatch   =   dispatch
};
2.2.2 为GSource提供stdin fd
static GPollFD fd   =
{
    .fd =   0,
    .events =   POLLIN,
    .revents    =   0
};
2.2.3 创建GSource
_source =   g_source_new( &funcs, sizeof( GSource ));
g_source_attach( _source, NULL );
2.2.4 为GSource添加stdin fd
g_source_add_poll( _source, &fd );
2.2.5 释放GSource引用
g_source_unref( _source );//一定要做,否则会内存泄漏
2.3 运行GMainLoop
g_main_loop_run (loop);


至此,命令行接口已创建完毕,程序运行后,用户可以通过控制台输入命令。开发者后续可以在mainloop上附加其它的GSource,使这个mainloop可以处理额外的并发事件。

你可能感兴趣的:(linux,glib)