QProcess的应用:杀死固定进程并重启进程
来源:互联网 发布:mac上电话轰炸 编辑:程序博客网 时间:2024/06/02 09:16
问题:这两天遇到项目程序莫名其妙的运行异常,那么可能需要自动终结该进程并重启。
思路:为了判断主程序是否正常运行,我们可以这样做,写一个辅助程序跟主程序通讯,这里采用本地udp socket的方式保持联系。主程序向辅助程序定时发送确认包。当辅助程序检测到主程序在一定时间内(假设是3s)没有发送数据包,那么辅助程序则判定主程序异常,先尝试性杀死进程,并自动重启。在这里考虑到这个程序是一个辅助程序,那么就打算把他做成一个后台服务程序。
先看下辅助程序:
//main.cpp
#include "Widget.h"#include <QApplication>#include <QProcess>int main(int argc, char *argv[]){ QApplication a(argc, argv); QProcess::startDetached("./xxx.exe"); Widget w; return a.exec();}
//widget.h
#ifndef WIDGET_H#define WIDGET_H#include <QWidget>#include <QUdpSocket>#include <QTimer>#include <QProcess>#include <QWidget>#include <QCloseEvent>namespace Ui {class Widget;}class Widget : public QWidget{ Q_OBJECTpublic: explicit Widget(QWidget *parent = 0); ~Widget();private slots: void slotReadyRead(); void slotTimeout();private: void initClass(); void killProcess(); void closeEvent(QCloseEvent*);private: QUdpSocket *udpSocket; QTimer *timer; QProcess process; QWidget *widget;private: Ui::Widget *ui;};#endif // WIDGET_H
//widget.cpp
#include "Widget.h"#include "ui_Widget.h"Widget::Widget(QWidget *parent) : QWidget(parent), ui(new Ui::Widget){ ui->setupUi(this); ui->plainTextEdit->appendPlainText("主程序运行中"); this->setWindowFlags(windowFlags() &~ (Qt::WindowMinMaxButtonsHint | Qt::WindowCloseButtonHint)); this->hide(); initClass();}Widget::~Widget(){ udpSocket->close(); udpSocket->deleteLater(); udpSocket = nullptr; timer->stop(); timer->deleteLater(); timer = nullptr; delete ui;}void Widget::slotReadyRead(){ while(udpSocket->hasPendingDatagrams()){ QByteArray datagram; datagram.resize(udpSocket->pendingDatagramSize()); QHostAddress senderHostAddress; quint16 senderPort; udpSocket->readDatagram(datagram.data(),datagram.size(),&senderHostAddress,&senderPort); qDebug()<<"UdpSocket Recevie:"<<senderHostAddress<<senderPort<<datagram; } timer->start(3000);}//定时如果到了,杀死进程并重启void Widget::slotKillProcess(){ this->show(); ui->plainTextEdit->appendPlainText("程序异常!!!"); ui->plainTextEdit->appendPlainText("正在解决异常......"); timer->stop(); killProcess(); ui->plainTextEdit->appendPlainText("正在重新启动......"); QProcess::startDetached("./xxx.exe"); this->hide();}void Widget::initClass(){ udpSocket = new QUdpSocket(this); if(udpSocket->bind(QHostAddress::LocalHost,20001,QAbstractSocket::ShareAddress)){ qDebug()<<"绑定20001端口成功"; }else{ qDebug()<<"绑定20001端口失败"; } connect(udpSocket,&QUdpSocket::readyRead,this,&Widget::slotReadyRead); timer = new QTimer(this); connect(timer,&QTimer::timeout,this,&Widget::slotKillProcess);}void Widget::killProcess(){ ui->plainTextEdit->appendPlainText("正在杀死进程xxx.exe"); QStringList args; args<<"/F"<<"/IM"<<"xxx.exe"<<"/T"; process.start(QString("TASKKILL"),args); process.waitForStarted(); process.waitForFinished(2000); ui->plainTextEdit->appendPlainText("已经杀死进程xxx.exe");}void Widget::closeEvent(QCloseEvent *e){ e->ignore();}
如程序所见,我这里是先启动辅助程序,并会自动启动主程序,并等待主程序发送数据包,当第一个数据包发送过来,则启动定时器,如果三秒之内主程序没有再发送数据包到此端口,那么则调用slotKillProcess()方法,先杀死进程并再重启程序。为了让程序在后台运行,这里调用窗体类的hide();当异常时,再显示窗口,待主程序启动完成后再次回到后台。为了显示进程消息,这里在UI文件放了个plainTextEdit。
`
下面是主程序与辅助程序相应的通讯类
//AckNormal.h
#ifndef ACKNORMAL_H#define ACKNORMAL_H#include <QObject>#include <QUdpSocket>#include <QMessageBox>#include <QTimer>class AckNormal : public QWidget{ Q_OBJECTpublic: explicit AckNormal(QWidget *parent = 0); ~AckNormal();signals:private slots: void slotTimeout();private: void initClass();private: QUdpSocket *udpSocket; QTimer *timer;};#endif // ACKNORMAL_H
//AckNormal.cpp
#include "AckNormal.h"AckNormal::AckNormal(QWidget *parent) : QWidget(parent) ,udpSocket(nullptr),timer(nullptr){ initClass();}AckNormal::~AckNormal(){ udpSocket->close(); udpSocket->deleteLater(); udpSocket = nullptr; timer->stop(); timer->deleteLater(); timer = nullptr;}void AckNormal::slotTimeout(){ QByteArray ba("online"); udpSocket->writeDatagram(ba,QHostAddress::LocalHost,20001);}void AckNormal::initClass(){ udpSocket = new QUdpSocket(this); if(!udpSocket->bind(QHostAddress::LocalHost,20000,QAbstractSocket::ShareAddress)){ QMessageBox::information(this,"Warning","绑定20000端口失败"); return; } timer = new QTimer(this); connect(timer,&QTimer::timeout,this,&AckNormal::slotTimeout); timer->start(1000);}
如上面程序所见,主程序启动后实例化AckNormal,会自动向辅助程序发送确认数据包。
至此一个简单的辅助程序就这样完成了。欢迎与各位Qt爱好者学习交流。
0 0
- QProcess的应用:杀死固定进程并重启进程
- 如何杀死Chrome进程并重启Chrome
- 杀死固定进程
- 根据应用的包名杀死进程
- 简单的杀死后台进程应用
- 简单的杀死后台进程应用
- 杀死应用进程的几种方法
- 自动kill rman 进程 ,并重启应用脚本
- 杀死进程的方法
- 杀死进程的方法
- 杀死进程的API
- Android杀死双进程应用
- qt进程间的通行 QProcess
- QProcess进程间双向通信
- Qt进程QProcess相关
- Qt 进程 QProcess
- QT新建进程 QProcess
- Qt 进程 QProcess
- 两个引用的库v4包冲突
- 第1周 项目(A)-9如何购买玫瑰?
- Android定时服务
- 自定义下拉刷新ListView
- android Matrix
- QProcess的应用:杀死固定进程并重启进程
- Centos 系统时间与当前时间相差和时区解决办法
- iOS锁屏问题解决方式
- 使用 GDB 调试 Linux 软件
- 进程间通讯总结 (6)
- 多target设置实战,自己也这么搞过,这篇写的蛮细的,mark一下吧。
- web前端 —— 移动端知识的一些总结
- jQuery中$.ajax()方法参数说明
- ZigBee HA1.2的前世今生