• c++实现的一个定时器实例


    /*
     * author: hjjdebug
     * date  : 2023年 09月 23日 星期六 11:52:29 CST
     * description: 用std::thread 实现了一个定时器,深刻理解一下定时器是怎样工作的.
     *              参考Timer.h, Timer.cpp
     */

    $  cat main.cpp
    #include "Timer.h"
    #include

    void onTimeout()
    {
        std::cout << "timer Time out!" << std::endl;
    }

    int main()
    {
        Timer *m_timer;
        m_timer = new Timer(1);
        m_timer->start_recycle(onTimeout); // 传入回调,循环定时,每1秒执行一次回调
        int loop=0;
        //按Ctrl -c 可以退出
        while(loop<5000)
        {
            sleep(1);
            loop++;
        }
        m_timer->stop();
        return 0;
    }

    $ cat Timer.h

    #ifndef TIMER_H
    #define TIMER_H

    #include
    #include
    #include
    #include
    #include

    typedef std::function CALL_BACK;
    class Timer {
    public:
        Timer(unsigned seconds);
        ~Timer();
        void start(CALL_BACK handle);
        void start_recycle(CALL_BACK handle);
        void stop();

    private:
        unsigned m_seconds = 0;
        bool m_isAlive = false;
    };

    #endif

    $ cat Timer.cpp

    #include "Timer.h"
    Timer::Timer(unsigned int seconds) {
        m_seconds = seconds;
    }
    Timer::~Timer() {
    }
    void Timer::start(CALL_BACK handle)
    {
        auto timeThread = [=] // timer 线程代码
            {
                for (unsigned int i = 0; i< (m_seconds * 1000); i++)
                {
                    if (m_isAlive)
                    {
                        usleep(1000); //睡眠1ms, 循环结束为m秒
                    }
                    else
                    {
                        return; //调用了stop, m_isAlive为false, 退出线程
                    }
                }
                if (m_isAlive)
                {
                    handle(); //回调函数
                }
                stop(); // 循环结束即退出,一遍即可.
                return;
            };
        
        if (!m_isAlive)
        {
            m_isAlive = true;
            std::thread t(timeThread); //创建线程, 主线程代码
            t.detach();
            printf("main thread id: %d\n",gettid());
        }
    }

    void Timer::start_recycle(CALL_BACK handle) {
        auto timeThread = [=]
            {
                while (m_isAlive) // 线程在循环, 直到外部stop
                {
                    //pthread_self() 头文件在pthread.h中,
                    //是pthread 库给每个进程中的每个线程定义的id,内核是不认识的
                    //数值很大, %ld, 我们看着也不方便
                    printf("timer pthread_self: %ld\n",pthread_self());
                    //gettid() 头文件在unistd.h中,由glibc来提供支持
                    printf("timer thread id: %d\n",gettid());
                    for (unsigned int i = 0; i < (m_seconds * 1000); i++)
                    {
                        if (m_isAlive)
                        {
                            usleep(1000);
                        }
                        else
                        {
                            return;
                        }
                    }
                    if (m_isAlive)
                    {
                        handle();
                    }
                }
            };
        
        if (!m_isAlive)
        {
            m_isAlive = true;
            std::thread t(timeThread);
            t.detach();
            printf("main thread id: %d\n",gettid());
        }
    }

    void Timer::stop() {
        m_isAlive = false;
    }
    /* 你可以用 ps -efT |grep "名称" 查看线程ID
       也可以用 ps -efL |grep "名称" 查看线程ID
     */

    执行结果

    /*
    执行程序, 打印了主线程id 11825 和线程id 11826
    $ ./cpp_timer
    main thread id: 11825
    timer pthread_self: 139903798966016
    timer thread id: 11826
    timer Time out!
    timer pthread_self: 139903798966016
    timer thread id: 11826

    用 ps -efT 或 ps -efL 也查到了cpp_timer 所有线程ID(11825,11826)
    $ ps -efT |grep cpp_timer
    hjj        11825   11825    9138  0 11:43 pts/1    00:00:00 ./cpp_timer
    hjj        11825   11826    9138  1 11:43 pts/1    00:00:00 ./cpp_timer
    hjj        11854   11854   10817  0 11:43 pts/3    00:00:00 grep --color=auto cpp_timer
    hjj@hjj-u7090:~/test/cpp-timer$ ps -efL |grep cpp_timer
    hjj        11825    9138   11825  0    2 11:43 pts/1    00:00:00 ./cpp_timer
    hjj        11825    9138   11826  1    2 11:43 pts/1    00:00:00 ./cpp_timer
    hjj        11866   10817   11866  0    1 11:44 pts/3    00:00:00 grep --color=auto cpp_timer

    小结: 所谓的定时器, 当时间到时执行某一个任务,是通过启动一个线程来实现的,
    等待时是timer线程在等待,执行时是timer线程在执行.
    调用线程和执行线程是不同的线程
    */

  • 相关阅读:
    PHP 自习室空位查询系统mysql数据库web结构apache计算机软件工程网页wamp计算机毕业设计
    Mybatis-Plus复杂语句多级嵌套分组带分页查询
    自动化运维机器人(RPA)在银行IT运维领域应用场景分析
    SpringMVC中的综合案例
    设计模式(三):抽象工厂模式
    Efficientnet网络
    c++运算符重载
    理解现货白银走势的关键
    RTE_Driver驱动框架和Keil下开发需要支持的xxx_DFP软件包分析
    【C++入门到精通】 哈希结构 | 哈希冲突 | 哈希函数 | 闭散列 | 开散列 [ C++入门 ]
  • 原文地址:https://blog.csdn.net/hejinjing_tom_com/article/details/133202411