C++ 如何降低应用程序的CPU使用率?

C++ 如何降低应用程序的CPU使用率?,c++,qt,qt5,qthread,C++,Qt,Qt5,Qthread,我的应用程序包括备份用户设置的特定sqlite数据库。此备份基于某些条件。因此,为了做到这一点,我正在使用一个worker对象(在QThread上运行)检查条件是否匹配。如果条件符合,我就接受备份。我的问题是,我已经检查了任务管理器,我的应用程序总是使用至少25%(因为线程正在运行)。如果我禁用自动备份,它将恢复正常。我做错了什么,还是这很正常?有人能告诉我如何保持cpu使用率低吗?下面是我的自动备份线程代码 void Automatic_Backup_Logic::Thread_Run() {

我的应用程序包括备份用户设置的特定sqlite数据库。此备份基于某些条件。因此,为了做到这一点,我正在使用一个worker对象(在QThread上运行)检查条件是否匹配。如果条件符合,我就接受备份。我的问题是,我已经检查了任务管理器,我的应用程序总是使用至少25%(因为线程正在运行)。如果我禁用自动备份,它将恢复正常。我做错了什么,还是这很正常?有人能告诉我如何保持cpu使用率低吗?下面是我的自动备份线程代码

void Automatic_Backup_Logic::Thread_Run()
{
    QSettings settings(ORGANISATION, APPLICATION_NAME);
    while(!m_Stop){
        // First check the backup type
        int backup_type = settings.value(BACKUP_TYPE).toInt();
        QTime BackupTime = qvariant_cast<QTime>(settings.value(BACKUP_TIME));

        // Check for backup time; if it's in range only then do backup
        if(!Check_Backup_Time(BackupTime)){
            continue;
        }

        switch (backup_type)
        {
            case BACKUP_TYPE_MANUAL:
            // do nothing here
                continue;

            case BACKUP_TYPE_DAILY:
                Backup_Daily();
                break;

            case BACKUP_TYPE_WEEKLY:
                Backup_Weekly();
                break;

            case BACKUP_TYPE_MONTHLY:
                Backup_Monthly();
                break;

            case BACKUP_TYPE_YEARLY:
                Backup_Yearly();
                break;

            default:
                break;
        }

        // Wait for the current backup minute to pass by to avoid multiple copies
        QTime t1 = qvariant_cast<QTime> (settings.value(BACKUP_TIME));
        while(t1.minute()==QTime::currentTime().minute()){
            if(m_Stop)
                return;
            QCoreApplication::processEvents();
        }
    }
}
void自动备份逻辑::线程运行()
{
QSettings设置(组织、应用程序和名称);
当(!m_停止){
//首先检查备份类型
int backup_type=settings.value(backup_type).toInt();
QTime BackupTime=qvariant_cast(settings.value(BACKUP_TIME));
//检查备份时间;如果仅在范围内,则执行备份
如果(!检查备份时间(备份时间)){
继续;
}
交换机(备用型)
{
案例备份类型手册:
//在这里什么也不做
继续;
案例备份\u类型\u每日:
每日备份();
打破
每周备份案例类型:
每周备份一次();
打破
案例备份\u类型\u每月:
每月备份一次();
打破
案例备份\u类型\u每年:
每年备份一次();
打破
违约:
打破
}
//等待当前备份分钟过去,以避免多个副本
QTime t1=qvariant_cast(settings.value(BACKUP_TIME));
而(t1.minute()==QTime::currentTime().minute()){
如果(m_停止)
返回;
QCoreApplication::processEvents();
}
}
}

PS:我正在通过标准的Qt过程运行这个线程,该过程创建一个工作线程,并使用moveToThread()函数,正如注释中所建议的,我在线程中设置了延迟,现在一切都正常工作了。谢谢大家

编辑代码

    // Check for backup time; if it's in range only then do backup
    while(!Check_Backup_Time(BackupTime) && !m_Stop){
        QThread::sleep(1);
        BackupTime = qvariant_cast<QTime>(settings.value(BACKUP_TIME));
    }
//检查备份时间;如果仅在范围内,则执行备份
同时(!检查备份时间(备份时间)&&!m_停止){
QThread::sleep(1);
备份时间=qvariant_cast(settings.value(备份时间));
}

正如评论中所建议的,我在我的线程中设置了延迟,现在一切都按预期工作。谢谢大家

编辑代码

    // Check for backup time; if it's in range only then do backup
    while(!Check_Backup_Time(BackupTime) && !m_Stop){
        QThread::sleep(1);
        BackupTime = qvariant_cast<QTime>(settings.value(BACKUP_TIME));
    }
//检查备份时间;如果仅在范围内,则执行备份
同时(!检查备份时间(备份时间)&&!m_停止){
QThread::sleep(1);
备份时间=qvariant_cast(settings.value(备份时间));
}

解决此问题的干净方法是使用Qt的信号/插槽机制

只需使用剩余的备份时间设置一个,并将其信号连接到备份插槽,如:

class Automatic_Backup_Logic {
public:
    Automatic_Backup_Logic() {
        connect(&mBackupTimer, &QTimer::timeout, this, &Automatic_Backup_Logic::performBackup);
    }

    void scheduleBackup(QTime backupTime) {
        int millisRemaining = getTimeRemaining(backupTime);
        mBackupTimer.singleShot(millisRemaining);
    }

private slots:
    void performBackup() {
    }

private:
    QTimer mBackupTimer;
}

解决这个问题的干净方法是使用Qt的信号/插槽机制

只需使用剩余的备份时间设置一个,并将其信号连接到备份插槽,如:

class Automatic_Backup_Logic {
public:
    Automatic_Backup_Logic() {
        connect(&mBackupTimer, &QTimer::timeout, this, &Automatic_Backup_Logic::performBackup);
    }

    void scheduleBackup(QTime backupTime) {
        int millisRemaining = getTimeRemaining(backupTime);
        mBackupTimer.singleShot(millisRemaining);
    }

private slots:
    void performBackup() {
    }

private:
    QTimer mBackupTimer;
}

除非
sleep()
Check\u Backup\u Time()
中有类似的内容,否则这里有一个繁忙的循环。我假设您的系统上有4个内核,而您的应用程序100%使用1个内核。因此,当无事可做时,您需要在某处调用sleep()(或usleep()或nanosleep()或poll())。@Rene因为我依赖于系统时间,所以可能无法使用sleep()。如果我错了,请纠正我你所说的依赖系统时间是什么意思?是什么阻止您为(…)使用类似于
std::this\u thread::sleep\u的东西?如果您无法预测下一次备份的大致时间,并且需要快速进行备份,则即使将其设置为一些较短的值(如0.1s甚至0.01s),也会有所帮助。建议您研究“QEventLoop::WaitForMoreEvents”标志。如果没有要处理的事件,它指示QEventLoop的processEvents方法进入等待状态。然后,您可以通过发布退出事件而不是设置标志退出processEvents循环。@感谢您指出,起初我认为应该等到下一次备份,但问题是,如果用户更改了时间,备份将丢失,现在我将睡眠5秒,现在一切正常。除非有
睡眠()
或类似的内容在
检查备份时间()
中,您有一个繁忙的循环。我假设您的系统上有4个内核,并且您的应用程序使用1个内核100%。因此,您需要一个sleep()(或usleep()或nanosleep()或poll())当无事可做时调用某个地方。@Rene由于我依赖于系统时间,我可能无法使用sleep()。如果我错了,请纠正我,依赖于系统时间是什么意思?是什么阻止您为(…)使用类似
std::this_thread::sleep_的内容
?如果您无法预测下一次备份的大致时间,并且需要快速进行备份,则即使将其设置为一些较短的值(如0.1s甚至0.01s),也会有所帮助。建议您研究“QEventLoop::WaitForMoreEvents”标志。如果没有要备份的事件,它会指示QEventLoop的processEvents方法进入等待状态进程。然后,您可以通过发布退出事件而不是设置标志来退出processEvents循环。@感谢您指出,起初我认为应该等到下一次备份,但问题是,如果用户更改了时间,备份将丢失,现在我让5秒睡眠,现在一切正常。以防万一,您“害怕”在最坏的情况下启动备份5秒太晚:你可以使用更短的睡眠时间,但你的应用程序不会占用更多的CPU时间。我认为即使睡眠10毫秒,也不会占用超过1-2%的CPU时间。以防万一你“害怕”