当前位置: 首页 > wzjs >正文

如何做单网页网站怎么做网络销售

如何做单网页网站,怎么做网络销售,wordpress 纯净主题,wordpress 去掉下划线大家有没有遇到过这样的情况:我们开发的某个应用程序,有时候在点击关闭按钮后,以为程序已经关闭结束,实际上程序进程还在后台运行。 这种有可能是程序中开启了某个子线程,当你关闭的时候,线程还在运行&…

大家有没有遇到过这样的情况:我们开发的某个应用程序,有时候在点击关闭按钮后,以为程序已经关闭结束,实际上程序进程还在后台运行。
这种有可能是程序中开启了某个子线程,当你关闭的时候,线程还在运行,导致程序看似关闭了,实际由于子线程的运行,并没有停止进程,而是转为在后台运行。
我们模拟一下这种情况。

1.问题描述

应用程序关闭后,去仍然在后台继续运行。

2.复现问题

我们使用QtCreator创建一个桌面应用程序作为测试程序,在“MainWindow”构造函数中启动一个子线程,这个子线程while循环一直运行,用来实时监测下面连接的下位机设备的连接状态。
主程序代码:

//主程序
MainWindow::MainWindow(QWidget *parent): QMainWindow(parent), ui(new Ui::MainWindow)
{ui->setupUi(this);setWindowTitle(QString("测试程序"));//开启线程QThreadPool::globalInstance()->setMaxThreadCount(4);ITask *pTask = new DevConnectTask();if(nullptr == pTask){logger()->info() << __FUNCTION__ << ", create MonitorCurrentTask failed!!!";return ;}QThreadPool::globalInstance()->start(pTask);QObject::connect(pTask, SIGNAL(signal_Result(int, bool)), this, SLOT(slotDevConnect(int, bool)), Qt::QueuedConnection);
}

子线程代码:

//头文件
//这里的父类ITask是继承自QObject和QRunnable的自定义的基类,不需要太纠结
class DevConnectTask : public ITask
{Q_OBJECT
public:DevConnectTask();
protected:void run() override;private:bool m_bToolConnected = false;
signals:void signal_Result(int nDev, bool bStatus);};
//cpp文件
//轮询设备连接状态
DevConnectTask::DevConnectTask()
{qRegisterMetaType<QString >("QString");setAutoDelete(true);
}void DevConnectTask::run()
{logger()->info() << __FUNCTION__ << ", DevConnectTask started---------";bool bTool = false;while (1) {//每隔1秒轮询一次,检测设备的连接状态Command::getInstance()->MonitorDevStatus(bTool, bPower);if(bTool != m_bToolConnected){m_bToolConnected = bTool;//状态改变,发送信号emit signal_Result(Dev, m_bToolConnected);}QThread::msleep(1000);}logger()->info() << __FUNCTION__ << ", DevConnectTask task end------------------";
}

首先,上面的代码逻辑上没有问题,主窗体开启后(或者通过按钮启动)启动子线程来监听外设的连接状况;
其次,程序运行上也没有问题,打开程序后能正常创建子线程,并启动子线程来监听外设的状态改变,也能正常收发状态改变的信号;
最后,关闭程序时发现问题,当你点击左上角关闭按钮后,桌面上貌似程序消失了,但当你打开任务管理器查看时,发现程序实际还在后台一直运行着。

3.分析问题

通过调试我们发现是开启的子线程惹的祸(实际用于正式的工程代码,可能需要调试,日志,及不断地屏蔽代码排除才能确认哪块引起);
那么这个子线程为什么会导致程序的进程并没有在关闭时结束呢?
我们需要回忆一下Qt中QThreadPool的工作原理。QThreadPool管理着一组线程,用于执行QRunnable任务。当调用start()时,任务会被添加到队列中,由线程池中的线程执行。默认情况下,全局线程池会在程序退出时等待所有任务完成,但如果任务中有无限循环或长时间运行的操作(本次测试程序,就是用while循环在无限的工作着),可能会导致等待时间过长,甚至无法退出。
在本测试程序中,当关闭程序时,主界面UI已经被关闭,资源已经释放了,但主进程开启的监听线程,由于while循环并没有因为某个预想的卡断将其退出,还一直在工作着,导致主进程也一直无法销毁,所以在任务管理器看到,程序依然在运行着。
这里在补充一些:程序关闭时线程没有正确停止,导致后台继续运行。其他可能的原因有几个:

  • ​任务中没有退出条件​:如果任务是一个无限循环,没有检查终止条件,线程池会一直等待任务完成,导致程序无法退出。
  • 没有正确清理线程池​:可能在关闭事件中没有正确请求线程池停止或等待任务完成。
  • 任务未设置自动删除​:如果QRunnable没有设置setAutoDelete(true),可能导致资源未释放,影响线程池的清理。

4.解决思路

根据上面的问题,我们可能的解决思路有以下几种:

  • 确保QRunnable任务可以被中断​:在任务中添加一个标志位,定期检查是否需要退出。
  • 在程序关闭时触发所有任务的停止标志​:在MainWindow的closeEvent中遍历所有任务,设置停止标志。
  • 正确清理线程池​:使用waitForDone等待任务结束,并设置超时时间,避免无限等待。
  • 处理未自动删除的任务​:确保QRunnable的自动删除开启,避免内存泄漏。

根据以上思路,得出一下解决方案:

  • 我们引入原子变量,通过原子标志位控制任务执行流程,实现可中断的QRunnable任务。
  • 在主窗口添加关闭事件处理,在关闭事件closeEvent中协调线程池关闭;
  • 线程任务启动与管理这块,我们要加上正确的启动方式​:有回应的管理线程任务;

大致流程如下:
在这里插入图片描述

5.代码优化

根据上面的解决方案,我们将代码进行优化:
首先,子线程中,我们加入原子标志“m_stopFlag”以及线程结束的信号“finished()”,并且用原子标志“m_stopFlag”控制线程的run()方法里的while循环,当线程结束时,发送信号“finished()”。
子线程代码:

//头文件
//这里的父类ITask是继承自QObject和QRunnable的自定义的基类,不需要太纠结
class DevConnectTask : public ITask
{Q_OBJECT
public:DevConnectTask();
protected:void run() override;private:bool m_bToolConnected = false;
signals:void signal_Result(int nDev, bool bStatus);public:
//设立原子标志std::atomic<bool> m_stopFlag{false};
signals:
//添加结束信号void finished();
};
//cpp文件
//轮询设备连接状态
DevConnectTask::DevConnectTask()
{qRegisterMetaType<QString >("QString");setAutoDelete(true);
}void DevConnectTask::run()
{logger()->info() << __FUNCTION__ << ", DevConnectTask started---------";bool bTool = false;//while循环收到原子标志控制while (!m_stopFlag.load(std::memory_order_acquire)) {//每隔1秒轮询一次,检测设备的连接状态Command::getInstance()->MonitorDevStatus(bTool, bPower);if(bTool != m_bToolConnected){m_bToolConnected = bTool;//状态改变,发送信号emit signal_Result(Dev, m_bToolConnected);}QThread::msleep(1000);}logger()->info() << __FUNCTION__ << ", DevConnectTask task end------------------";//线程结束时发送结束信号emit finished();
}

主程序中,我们添加一个QList的成员变量“m_activeTasks”原来记录子线程(可能有多个子线程,所以用QList),并且加上线程结束信号“finished()”的响应处理,同时,我们要加上关闭事件“closeEvent()”,用以处理当主程序关闭时,如果有线程在循环里运行,就通过原子标志控制其退出循环,结束线程。
主程序代码:

//主程序
MainWindow::MainWindow(QWidget *parent): QMainWindow(parent), ui(new Ui::MainWindow)
{ui->setupUi(this);setWindowTitle(QString("测试程序"));//开启线程QThreadPool::globalInstance()->setMaxThreadCount(4);ITask *pTask = new DevConnectTask();if(nullptr == pTask){logger()->info() << __FUNCTION__ << ", create MonitorCurrentTask failed!!!";return ;}// 加入跟踪列表,m_activeTasks在头文件定义:QList<ITask*> m_activeTasks;m_activeTasks.append(pTask);QObject::connect(pTask, &ITask::finished, [this, pTask](){// 线程结束信号处理m_activeTasks.removeOne(pTask);logger()->info() << __FUNCTION__ << "线程任务完成";});QThreadPool::globalInstance()->start(pTask);QObject::connect(pTask, SIGNAL(signal_Result(int, bool)), this, SLOT(slotDevConnect(int, bool)), Qt::QueuedConnection);
}
//重写关闭事件
void MainWindow::closeEvent(QCloseEvent *event) {// 设置所有任务的停止标志for(auto task : m_activeTasks){task->m_stopFlag.store(true, std::memory_order_release);}// 清理线程池QThreadPool::globalInstance()->clear();  // 移除未开始的任务QThreadPool::globalInstance()->waitForDone(100);  // 等待最多100ms// 验证线程池状态logger()->error() << __FUNCTION__ << "关闭前,活动线程数:" << QThreadPool::globalInstance()->activeThreadCount();// 必须调用以完成关闭event->accept();
}

至此,经过验证测试,当关闭程序时,所有线程均能一一结束,确保主进程也彻底结束。大家还有什么其他方法,欢迎留言分享。

http://www.dtcms.com/wzjs/34897.html

相关文章:

  • 做美女网站违法不啊惠州搜索引擎seo
  • thinkphp 显示第三方网站图片软文发布
  • 哪个网站能在家做兼职百度指数数据官网
  • 珠海网站开发软件百度授权代理商
  • 泰州网站建设报价太原竞价托管公司推荐
  • tint-k主题做企业网站广告公司业务推广
  • 太仓网络公司windows优化软件哪个好
  • 乐陵建设网站seo是哪个国家
  • 网页上本地网站搜索怎样做泰安百度推广电话
  • 最超值的锦州网站建设软文文案范文
  • 网站模板兼容手机端seo sem推广
  • 网页访问限制怎么解除系统优化是什么意思
  • 企业网站不备案郑州网络营销公司
  • 网站做淘宝联盟晚上免费b站软件
  • 上海网站制作建设怎么样aso关键词搜索优化
  • 公司网站制作深圳国外推广网站有什么
  • 科技公司网站网页深圳最新疫情
  • 山西两学一做网站登录怎么注册自己公司的网址
  • 新兴县做网站的网络广告营销典型案例
  • 网站建设的基本元素班级优化大师官方免费下载
  • wordpress 伪原创 插件竞价托管优化公司
  • wordpress密码进入网站互联网营销专业
  • 做英文网站挂谷歌广告西安竞价托管
  • wordpress blogroll成品网站seo
  • nginx网站301重定向怎么做免费个人网站申请
  • 网站内容建设运维服务龙华线上推广
  • 怎么做网站报价表网络营销品牌策划
  • 中国著名b2b电子商务网站seo搜索优化
  • 网站建设一般多少钱比较合适杭州seo顾问
  • 网站建设流程教程媒体网站