`
mypyg
  • 浏览: 549408 次
  • 性别: Icon_minigender_1
  • 来自: 成都
社区版块
存档分类
最新评论

GSource 创建时各函数的用处

 
阅读更多
1.prepare:

    进入睡眠之前,在g_main_context_prepare里,mainloop调用所有Source的prepare函数,计算最小的timeout时间,该时间决定下一次睡眠的时间。

2.check:

    poll被唤醒后,在g_main_context_check里,mainloop调用所有Source的check函数,检查是否有Source已经准备好了。如果poll是由于错误或者超时等原因唤醒的,就不必进行dispatch了。

3.dispatch:

    当有Source准备好了,在g_main_context_dispatch里,mainloop调用所有Source的dispatch函数,去分发消息。

4.finalize:

    在Source被移出时,mainloop调用该函数去销毁Source。

    

实例验证:

    1.创建两个GSource,一个2秒醒一次,一个3秒醒一次。

   
#include <stdio.h>
    #include <stdlib.h>
    #include <stdarg.h>
    #include <string.h>

    #include <glib.h>

    typedef struct _DemoSource DemoSource;
    struct _DemoSource
    {
      GSource               source;
      int   interval;
      GTimeVal              last;
    };

    DemoSource *s1, *s2;
    const char* cur_source_name = NULL;

    static glong my_time_val_difference (const GTimeVal *compare, const GTimeVal *now)
    {
      return (compare->tv_sec - now->tv_sec) * 1000 + (compare->tv_usec - now->tv_usec) / 1000;
    }

    static const char* get_source_str( GSource* source_ )
    {
            if( (unsigned int)source_ == (unsigned int)s1 ) return "s1";
            else if( (unsigned int)source_ == (unsigned int)s2 ) return "s2";

            return "unkown";
    }

    static gboolean prepare_func( GSource *source_, gint *timeout )
    {
            DemoSource* source = (DemoSource*)source_;
            GTimeVal now, target;
            glong diff;

            cur_source_name = get_source_str( source_ );

            g_source_get_current_time( source_, &now );

            target = source->last;
            g_time_val_add( &target, source->interval );

            diff = my_time_val_difference( &now, &target );

            printf("-----%s Enter -----\n", __FUNCTION__);

            if( diff >= 0 )
            {
                    *timeout = 0;
                    printf( "Source %s need to dispatch right now. D:%d\n", cur_source_name, diff );
                    return TRUE;
            }
            else
            {
                    *timeout = -diff;
                    printf( "Source %s need to sleep %d ms.\n", cur_source_name, *timeout );
                    return FALSE;
            }
            printf("-----%s Exit-----\n", __FUNCTION__);
    }

    static gboolean check_func( GSource* source_ )
    {
            DemoSource* source = (DemoSource*)source_;
            GTimeVal now, target;
            glong diff;

            cur_source_name = get_source_str( source_ );

            g_source_get_current_time( source_, &now );

            target = source->last;
            g_time_val_add( &target, source->interval );

            diff = my_time_val_difference( &now, &target );

            printf("-----%s Enter -----\n", __FUNCTION__);
            if( diff >= 0 )
            {
                    printf("Yes. Source %s need to dispatch.\n", cur_source_name );
                    return TRUE;
            }
            else
            {
                    printf("No. Source %s want to sleep.\n", cur_source_name );
                    return FALSE;
            }
            printf("-----%s Exit-----\n", __FUNCTION__);
    }

    static gboolean dispatch_func(GSource *source_, GSourceFunc callback, gpointer user_data)
    {
            cur_source_name = get_source_str( source_ );
            printf("-----%s Enter -----\n", __FUNCTION__);
            DemoSource* source = (DemoSource*)source_;
            g_get_current_time( &source->last );
            printf("Source %s dispatched.\n", cur_source_name);
            printf("-----%s Exit-----\n", __FUNCTION__);
    }

    static void finalize_func( GSource* source_ )
    {
            cur_source_name = get_source_str( source_ );
            printf("-----%s Enter -----\n", __FUNCTION__);
            printf("Source %s finalized.\n", cur_source_name );
            printf("-----%s Exit-----\n", __FUNCTION__);
    }

    SourceFuncs source_funcs =
    {
            prepare_func,
            check_func,
            dispatch_func,
            finalize_func,
    };

    int main( int argc, char** argv )
    {
            GMainLoop* loop;

            loop = g_main_loop_new( NULL, TRUE );

            s1 = (DemoSource*)g_source_new( &source_funcs, sizeof(DemoSource) );
            s2 = (DemoSource*)g_source_new( &source_funcs, sizeof(DemoSource) );
            s1->interval = 2000*1000;               //ms
            s2->interval = 3000*1000;

            g_get_current_time( &s1->last );
            g_get_current_time( &s2->last );

            g_source_attach( (GSource*)s1, NULL );
            g_source_attach( (GSource*)s2, NULL );

            printf( "s1 addr:0x%x\n", (unsigned int)s1 );
            printf( "s2 addr:0x%x\n", (unsigned int)s2 );

            g_main_loop_run( loop );

            return 0;
    }


    2.编译后的输出结果:

    s1 addr:0x804ae98
    s2 addr:0x804b500
    -----prepare_func Enter -----
    Source s1 need to sleep 2000 ms.
    -----prepare_func Enter -----
    Source s2 need to sleep 3000 ms.


    -----check_func Enter -----
    Yes. Source s1 need to dispatch.
    -----check_func Enter -----
    No. Source s2 want to sleep.
    -----dispatch_func Enter -----
    Source s1 dispatched.
    -----dispatch_func Exit-----
    -----prepare_func Enter -----
    Source s1 need to sleep 2000 ms.
    -----prepare_func Enter -----
    Source s2 need to sleep 1000 ms.


    -----check_func Enter -----
    No. Source s1 want to sleep.
    -----check_func Enter -----
    Yes. Source s2 need to dispatch.
    -----dispatch_func Enter -----
    Source s2 dispatched.
    -----dispatch_func Exit-----
    -----prepare_func Enter -----
    Source s1 need to sleep 1000 ms.
    -----prepare_func Enter -----
    Source s2 need to sleep 3000 ms.

    

    -----check_func Enter -----
    Yes. Source s1 need to dispatch.
    -----check_func Enter -----
    No. Source s2 want to sleep.
    -----dispatch_func Enter -----
    Source s1 dispatched.
    -----dispatch_func Exit-----
    -----prepare_func Enter -----
    Source s1 need to sleep 2000 ms.
    -----prepare_func Enter -----
    Source s2 need to sleep 2000 ms.

    3.结果分析:

       (1)首先2个source的prepare函数被调用。一个要呼2秒,一个要呼3秒

       (2)2秒后2个source的check函数被调用。s1确实是要dispatch,s2回答不关我事,不要叫我

       (3)s1被dispatch。

       (4)两个source的prepare函数再次调用。一个要呼2秒,一个再继续呼1秒

       (5)再次check

       (6)再次dispatch。

        循环往复

    4.个人理解:

       mainloop相当于管家,先问下(prepare())诸位大概什么时候用餐(dispatch())。统计后就设一个闹钟,到时提醒。但是由于没记下各自的时间,所以让大家再确认一下是不是自己(check()),如果check返回true,那么就被dispatch()了。

       或者由于外界事件,比如冰淇淋在大家呼呼的过程中送来了,管家就叫大家check()一下。虽然没到时间,但是如果check()返回true,那么也直接dispatch()了

分享到:
评论

相关推荐

    VSTO创建EXCEL自定义函数

    在VSTO中如何利用C#创建EXCEL自定义函数

    oracle 创建wm_concat函数

    ### Oracle 创建wm_concat函数 #### 知识点一:Oracle 10G及以下版本的wm_concat函数自定义实现 在Oracle 10G及更早版本中,并没有内置的`wm_concat`函数,该函数主要用于对一组字符串进行连接操作。为了在这些...

    db2调自定义函数(小例)

    本文将深入探讨如何在DB2中创建和调用自定义函数,通过具体的示例代码,展示这一过程的关键步骤。 ### 创建自定义函数:理论与实践 在DB2中创建自定义函数涉及以下几个关键步骤: 1. **编写源代码**:首先,你...

    MATLAB中创建自定义绘图函数的全面指南

    在MATLAB中,自定义绘图函数是一种强大的工具,它允许用户根据自己的需求创建特定的图形和可视化效果。这些函数可以封装复杂的绘图逻辑,使得绘图过程更加高效和可重复使用。本文将详细介绍如何在MATLAB中创建自定义...

    [Labview]用数组创建函数创建一个二维数组显示件,成员为:

    用数组创建函数创建一个二维数组显示件,成员为: 4 5 6 1 2 3 3 4 5 6 1 2 2 3 4 5 6 1 1 2 3 4 5 6 编程将上述创建的数组转置为: 1 2 3 4 2 3 4 5 3 4 5 6 4 5 6 1 5 6 1 2 6 1 2 3

    创建有导出函数的内核驱动程序

    本篇将详细探讨如何创建一个具有导出函数的内核驱动程序,以及涉及的相关知识点。 一、驱动程序的结构与功能 驱动程序通常包含初始化、设备控制、中断处理和清理等核心功能。在添加导出函数后,这些功能可以被用户...

    c#对SQLite创建自定义函数

    本篇文章将深入探讨如何在C#中为SQLite创建自定义函数,以满足特定业务需求。 首先,理解SQLite自定义函数的概念。SQLite允许开发者扩展其内置功能,通过创建用户自定义函数(UDF,User Defined Function),可以...

    mfc下实现回调函数

    在Microsoft Foundation Classes (MFC) 中,回调函数是一种特殊类型的函数,它允许用户代码与库或操作系统进行交互,尤其是在处理异步事件时。回调函数通常作为参数传递给其他函数,以便在特定事件发生时调用。在MFC...

    虚函数的创建和调用

    大学基础c++代码,自习c++可用,虚函数的创建和调用

    Oracle设置用户密码复杂度的函数

    本文将详细介绍如何通过创建一个名为`my_password_verify`的自定义函数来实现对Oracle用户密码复杂度的控制。 #### 一、背景介绍 在Oracle数据库中,默认情况下并没有内置的功能可以直接限制用户的密码复杂度。...

    MySQL数据库:存储函数的创建.pptx

    MySQL数据库:存储函数的创建.pptx

    构造、析构函数

    构造函数的主要作用是在创建对象时初始化该对象。构造函数可以重载,这意味着一个类中可以有多个构造函数,只要它们的参数列表不同即可。 例如,考虑`Location`类,它定义了三个构造函数:无参构造函数、一个接受...

    Oracle 11gR2创建PASSWORD_VERIFY_FUNCTION对应密码复杂度验证函数步骤.doc

    例如,你可以创建一个名为`资源文件名`的配置,设置`FAILED_LOGIN_ATTEMPTS`为10,`PASSWORD_LIFE_TIME`为180天,并且使用`PASSWORD_VERIFY_FUNCTION`指定我们即将创建的验证函数`verify_function_11G`。 ```sql ...

    DLL创建与函数调用规则

    本篇文章将详细探讨DLL的创建以及函数调用规则。 首先,DLL分为几种类型: 1. Non-MFC DLL:这类DLL不依赖于MFC(Microsoft Foundation Classes)库,而是直接使用C语言编写,输出的函数通常采用标准C接口,因此...

    hive 创建自定义函数 和 hive加载说明

    然而,有时Hive的内置函数并不能满足所有的业务需求,这时我们就需要创建自定义函数(UDF,User Defined Function)。这篇博文主要探讨了如何在Hive中创建自定义函数以及如何加载它们,这对于深化Hive的使用和解决...

    ArcGIS教程:经验半变异函数

    在创建经验半变异函数时,我们需要注意计算局限性,特别是当输入数据集的观测值数大于 5000 时,Geostatistical Analyst 将为结构分析和半变异函数模型拟合随机选择 5000 个观测值。这可能会影响模型的估计结果。 ...

    C++ 线程函数是类的成员函数

    由于成员函数需要对象实例才能被调用,因此在创建线程时需要提供对象的引用或指针。 ```cpp MyClass obj; std::thread my_thread(&MyClass::threadFunction, &obj, 42); // 42 是传递给成员函数的参数 ``` 三、...

    隶属函数在MATLAB中应用_隶属度函数_隶属函数matlab_隶属度_隶属函数在MATLAB中应用_

    MATLAB提供了丰富的函数库来创建和操作各种类型的隶属函数,如三角函数、梯形函数、高斯函数等。例如,可以使用`trapezoid`函数构建梯形函数,`gaussmf`函数构建高斯型函数。这些函数允许用户自定义参数,以适应特定...

    构造函数和析构函数PPT课件.pptx

    构造函数是C++编程语言中的一种特殊的成员函数,它是在创建对象时由系统自动执行的函数。构造函数的主要功能是将对象初始化,并执行一些必要的操作,以便对象能够正确地工作。构造函数的定义必须与类名相同,并且不...

    vc++ 函数经典 vc++ 函数经典 vc++ 函数经典

    C++11引入了lambda表达式,它提供了一种快速创建匿名函数的方式,常用于函数对象和算法。 以上是VC++函数经典的一些关键概念,掌握这些知识点将有助于编写高效、灵活的C++程序。在实际编程中,应结合具体需求灵活...

Global site tag (gtag.js) - Google Analytics