尽管没有在任何地方使用 std::thread
或 QThread
,但仍然遇到以下问题:
- 始终来自 Qt 的运行时调试错误日志:
QObject::connect: Cannot queue arguments of type 'QAbstractSocket::SocketError'
(Make sure 'QAbstractSocket::SocketError' is registered using qRegisterMetaType().) TcpSocket::flush()
方法间歇性崩溃;
我用这个方法来确保TCP立即写入;现在,有时应用程序会在使用SIGPIPE
的方法中崩溃
在网上搜索时,发现人们建议要解决第一个问题(即元错误),当我们有多个线程时,我需要使用 qRegisterMetaType()
进行注册。
同样的多线程也被认为是第二个问题的原因;请参阅this和 this .
但我没有超过 1 个线程!
我的套接字代码如下所示:
struct Socket : public QSslSocket
{
Q_OBJECT public:
void ConnectSlots ()
{
const auto connectionType = Qt::QueuedConnection;
connect(this, SIGNAL(readyRead()), this, SLOT(ReceiveData()), connectionType);
connect(this, SIGNAL(disconnected()), this, SLOT(Disconnected()), connectionType);
connect(this, SIGNAL(error(QAbstractSocket::SocketError)),
this, SLOT(Error(QAbstractSocket::SocketError)), connectionType);
// ^^^^^^^ error comes whether I comment this or not
}
public slots:
void ReceiveData () { ... }
void Disconnected () { ... }
void Error () { ... }
}
问题:Qt 是否自己创建任何内部线程用于读/写目的? (我希望不是)。如何解决以上两个问题?
最佳答案
我认为问题与线程无关,而是 QAbstractSocket::SocketError
类型参数和 Qt::QueuedConnection< 的组合
这导致了问题。
查看 Qt5.8 源代码中的各种 connect
实现,如果将 Qt::QueuedConnection
指定为连接类型,则检查信号的参数类型将被执行。类似...
int *types = 0;
if ((type == Qt::QueuedConnection)
&& !(types = queuedConnectionTypes(signalTypes.constData(), signalTypes.size()))) {
return QMetaObject::Connection(0);
}
如果任何类型未注册,queuedConnectionTypes
将返回空指针。
因此,如果连接已排队,则信号使用的所有参数都必须注册,无论插槽是否使用它们。为了避免错误,请确保您调用...
qRegisterMetaType<QAbstractSocket::SocketError>();
在使用 QAbstractSocket::SocketError
参数和 Qt::QueuedConnection 组合调用 connect
之前的某个时刻。
关于c++ - QTcpSocket 或 QSslSocket 是否自动创建读/写线程?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/45077696/