c++自定义定时器

我们公司最近被qt公司盯上说侵权,现在在去qt化,本博文的定时器可以代替QTimer。

#ifndef TIMEERCPP_H
#define TIMEERCPP_H

#include <thread>
#include <atomic>

class Timer
{
public:
    void setInterval(int interval);
    ~Timer();
    void stop();
    void start();

private:
    void run();
    std::atomic<bool> active{false};
    int interval{1000};
    std::thread workerThread;
};

#endif

#include "timercpp.h"
#include <iostream>
#include <thread>

void Timer::setInterval(int interval)
{
    this->interval = interval;
}

Timer::~Timer()
{
    if(active.load())
    {
        stop();
    }
}

void Timer::stop()
{
    active = false;
    if(workerThread.joinable())
    {
        workerThread.join();
    }
}

void Timer::start()
{
    if(active.load())
    {
        stop();
    }
    active = true;
    workerThread = std::thread(&Timer::run, this);
}

void Timer::run()
{
    std::cout<<"run"<<std::endl;

    while(active.load())
    {
        std::this_thread::sleep_for(std::chrono::milliseconds(interval));
        if(!active.load())
            return;

        std::cout<<"xxx"<<std::endl;
    }
}

这个代码可用,不卡GUI,缺点是每创建一个对象就创建一个子线程。

下面这个代码则进行了优化,使用一个子线程统一处理:

#ifndef TIMEERCPP_H
#define TIMEERCPP_H

#include <thread>
#include <atomic>
#include <list>
#include <mutex>
#include <chrono>

class Timer
{
public:
    Timer();
    ~Timer();
    void updateTime(long long currentTime_millisec);
    void setInterval(int newInterval);

private:
    long long millisec_since_epoch_currentTime;
    int interval{1000};
    int GC{0};
};

class TimerEventManager
{
public:
    static TimerEventManager* getInstance();
    ~TimerEventManager();
    void addTimer(Timer * timer);
    void removeTimer(Timer * timer);
    void start();
    void stop();

private:
    void run();
    std::list<Timer*> list;
    std::atomic<bool> active{false};
    std::thread workerThread;
    std::mutex mutex;
};

#endif

TimerEventManager *TimerEventManager::getInstance()
{
    static TimerEventManager manager;
    return &manager;
}

TimerEventManager::~TimerEventManager()
{
    active = false;
    if(workerThread.joinable())
    {
        workerThread.join();
    }
}

void TimerEventManager::addTimer(Timer *timer)
{
    std::lock_guard<std::mutex> lock(mutex);
    list.push_back(timer);
}

void TimerEventManager::removeTimer(Timer *timer)
{
    std::lock_guard<std::mutex> lock(mutex);
    list.remove(timer);
}

void TimerEventManager::start()
{
    active.store(true);
    workerThread = std::thread(&TimerEventManager::run,this);
}

void TimerEventManager::stop()
{
    active.store(false);
    if (workerThread.joinable())
    {
        workerThread.join();
    }
}

void TimerEventManager::run()
{
    while(active.load())
    {
        std::this_thread::sleep_for(std::chrono::milliseconds(50));
        if (!active.load())
            return;

        auto currentTime_millisec = std::chrono::duration_cast<std::chrono::milliseconds>(std::chrono::system_clock::now().time_since_epoch()).count();

        std::lock_guard<std::mutex> lock(mutex);
        for (auto& timer : list)
        {
            timer->updateTime(currentTime_millisec);
        }
    }
}

Timer::Timer()
{
    //获取时间点相对于 epoch(通常是 1970 年 1 月 1 日 00:00:00 UTC)的持续时间的函数。
    millisec_since_epoch_currentTime = std::chrono::duration_cast<std::chrono::milliseconds>(std::chrono::system_clock::now().time_since_epoch()).count();
    TimerEventManager::getInstance()->addTimer(this);
}

Timer::~Timer()
{
    TimerEventManager::getInstance()->removeTimer(this);
}

void Timer::updateTime(long long currentTime_millisec)
{
    int t = (currentTime_millisec - millisec_since_epoch_currentTime) / interval;
    if(t > GC)
    {
        GC = t;
        std::cout<<"超时 interval = "<<interval<<std::endl;
    }
}

void Timer::setInterval(int newInterval)
{
    interval = newInterval;
}
  • 2
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 6
    评论
### 回答1: 可以先将定时器框架的功能和结构进行抽象,然后根据抽象的功能结构来实现对C语言的实现。可以采用C语言的多线程编程来实现定时器框架,如使用POSIX线程和timer_create()函数来实现定时器框架,并使用sigaction()函数来处理定时器到期时的信号。 ### 回答2: 设计一个C定时器框架需要考虑以下几个方面: 1. 定时器的数据结构:可以采用链表或优先队列来存储定时器事件,每个结点包含定时时间、回调函数和参数等信息。 2. 定时器的接口:提供初始化、启动、停止、添加事件、删除事件等基本操作的接口函数。 3. 定时器的调度机制:可以使用一个循环结构不断检查定时器事件的触发情况,一旦达到定时时间,就执行相应的回调函数。 4. 定时器的精度和性能:可以通过选择合适的时钟精度来控制定时器触发的准确性和性能开销。例如,使用系统时钟提供的高精度定时器API,或者通过设置时间片大小来调节。 5. 多线程应用和线程安全:在多线程应用中,需要考虑线程同步和互斥机制,确保并发操作不会导致数据竞争或死锁等问题。 6. 容错和异常处理:设计定时器框架时需要考虑异常情况的处理方式,例如定时器触发出错、回调函数异常、时钟漂移等问题,可以采用适当的错误处理机制和日志记录。 总之,设计一个C定时器框架需要充分考虑功能需求、性能需求和安全需求,合理选择数据结构和算法,并进行充分的测试和优化,以确保高效且可靠地实现定时器功能。 ### 回答3: 设计一个C定时器框架可以帮助我们实现定时操作,并且提高程序的效率。以下是一种设计思路。 首先,我们需要定义一个定时器结构体,其中包含一个时间戳变量用于记录定时操作的时间点,一个函数指针用于指向定时器触发时需要执行的函数,以及其他可选的自定义参数。 接下来,我们需要实现一些基本的功能函数。首先是初始化函数,用于初始化定时器框架的内部变量和数据结构。然后是一个定时注册函数,用于注册一个定时器。该函数需要接受一个时间间隔参数,并将定时器结构体添加到定时器队列中。我们还可以实现一个取消注册函数,用于取消已注册的定时器。这样,我们就可以动态地添加和删除定时器。 为了实现定时器的触发机制,我们可以采用轮询的方式。在程序的主循环中,我们使用一个循环遍历定时器队列,检查每个定时器的时间戳是否到达当前时间。如果到达,则调用该定时器对应的函数指针执行具体的任务。如果没有到达,则继续下一个定时器的检查。 在设计中,我们还需要考虑如何处理较短时间间隔的定时任务。可以使用一个最小时间间隔的变量来设置定时器的触发频率,以避免频繁触发定时器,降低程序效率。 此外,为了提高程序的效率,我们可以使用优先队列或二叉堆来组织定时器队列,以保证定时器触发顺序的准确性。 最后,我们还可以实现一些附加功能,如定时器暂停、恢复等,以满足不同的需求。 通过这样一个设计,我们可以灵活地管理和控制定时任务,提高程序的时间管理能力和效率。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 6
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值