为什么不在析构函数中关闭串口?
Why not closed serial port in destructor?
我使用 socat 创建虚拟串口:
$socat -d -d pty,raw,echo=0 pty,raw,echo=0
然后通过我的程序打开它并通过 Ctrl+c 停止程序,在 运行 之后再次让我这条消息:
"Failed to open port pts/9, error: Device or resource busy"
#include "serport.h"
#include <QCoreApplication>
int main(int argc, char *argv[])
{
QCoreApplication a(argc, argv);
QSerialPort serialPort;
serialPort.setPortName("/dev/pts/9");
serialPort.setBaudRate(QSerialPort::Baud9600);
if (!serialPort.open(QIODevice::ReadOnly)) {
qDebug() << QObject::tr("Failed to open port %1, error: %2").arg(serialPort.portName()).arg(serialPort.errorString()) << endl;
return 1;
}
serport port(&serialPort,&a);
a.connect(&a, SIGNAL(aboutToQuit()), &serialPort, SLOT(deleteLater()));
a.connect(&a, SIGNAL(aboutToQuit()), &port, SLOT(deleteLater()));
return a.exec();
}
serport.h
#ifndef SERPORT_H
#define SERPORT_H
#include <QDebug>
#include <QObject>
#include <QtSerialPort/QSerialPort>
class serport : public QObject
{
Q_OBJECT
public:
explicit serport(QSerialPort *serialPort, QObject *parent);
~serport();
QSerialPort *port;
signals:
public slots:
};
#endif // SERPORT_H
serport.cpp
#include "serport.h"
serport::serport(QSerialPort *serialPort, QObject *parent) : QObject(parent),port(serialPort){ }
serport::~serport(){
qDebug()<<"closing";
port->close();
}
如何正确关闭端口?为什么在我的程序中从来没有看到 "closing" 消息?
这是关于在不调用所有释放处理程序的情况下退出进程。更多 Linux-specific 而不是 Qt。但是你仍然可以做点什么。确保使用 Qt 为 Ctrl-c 创建用户处理程序。
QApplication: How to shutdown gracefully on Ctrl-C
你自己说你 "stop the programm by Ctrl+c"。
这样做就是向程序进程发送 SIGINT 信号。这种信号的典型结果[*] 是终止进程,参见signal(7)。
进程然后 "die" 在其执行的任何位置。在你的例子中,很可能在它的主要 Qt 事件循环中。您似乎假定您的程序会干净地终止,例如会自动神奇地调用您创建的对象的所有析构函数。这绝对是不是的情况。 serport 的析构函数未被调用,因此端口未关闭。
您必须实现一种完全终止程序的方法。信号处理程序可能是一种方式。可能有 others/better,这取决于您希望程序在完成时的行为方式(如 "code complete" 中那样完成)。
[*]:我说 "typical" 是因为许多程序(守护进程)为 SIGINT 实现了一个处理程序,它们用来重新读取它们的配置文件。这使您能够 "refresh" 配置守护进程服务器而无需停止然后重新启动它。
我使用 socat 创建虚拟串口:
$socat -d -d pty,raw,echo=0 pty,raw,echo=0
然后通过我的程序打开它并通过 Ctrl+c 停止程序,在 运行 之后再次让我这条消息:
"Failed to open port pts/9, error: Device or resource busy"
#include "serport.h"
#include <QCoreApplication>
int main(int argc, char *argv[])
{
QCoreApplication a(argc, argv);
QSerialPort serialPort;
serialPort.setPortName("/dev/pts/9");
serialPort.setBaudRate(QSerialPort::Baud9600);
if (!serialPort.open(QIODevice::ReadOnly)) {
qDebug() << QObject::tr("Failed to open port %1, error: %2").arg(serialPort.portName()).arg(serialPort.errorString()) << endl;
return 1;
}
serport port(&serialPort,&a);
a.connect(&a, SIGNAL(aboutToQuit()), &serialPort, SLOT(deleteLater()));
a.connect(&a, SIGNAL(aboutToQuit()), &port, SLOT(deleteLater()));
return a.exec();
}
serport.h
#ifndef SERPORT_H
#define SERPORT_H
#include <QDebug>
#include <QObject>
#include <QtSerialPort/QSerialPort>
class serport : public QObject
{
Q_OBJECT
public:
explicit serport(QSerialPort *serialPort, QObject *parent);
~serport();
QSerialPort *port;
signals:
public slots:
};
#endif // SERPORT_H
serport.cpp
#include "serport.h"
serport::serport(QSerialPort *serialPort, QObject *parent) : QObject(parent),port(serialPort){ }
serport::~serport(){
qDebug()<<"closing";
port->close();
}
如何正确关闭端口?为什么在我的程序中从来没有看到 "closing" 消息?
这是关于在不调用所有释放处理程序的情况下退出进程。更多 Linux-specific 而不是 Qt。但是你仍然可以做点什么。确保使用 Qt 为 Ctrl-c 创建用户处理程序。
QApplication: How to shutdown gracefully on Ctrl-C
你自己说你 "stop the programm by Ctrl+c"。
这样做就是向程序进程发送 SIGINT 信号。这种信号的典型结果[*] 是终止进程,参见signal(7)。
进程然后 "die" 在其执行的任何位置。在你的例子中,很可能在它的主要 Qt 事件循环中。您似乎假定您的程序会干净地终止,例如会自动神奇地调用您创建的对象的所有析构函数。这绝对是不是的情况。 serport 的析构函数未被调用,因此端口未关闭。
您必须实现一种完全终止程序的方法。信号处理程序可能是一种方式。可能有 others/better,这取决于您希望程序在完成时的行为方式(如 "code complete" 中那样完成)。
[*]:我说 "typical" 是因为许多程序(守护进程)为 SIGINT 实现了一个处理程序,它们用来重新读取它们的配置文件。这使您能够 "refresh" 配置守护进程服务器而无需停止然后重新启动它。