带有 QtConcurrent::run 的线程服务器

发布于 2024-11-15 18:53:15 字数 2919 浏览 3 评论 0原文

我正在尝试开发一个线程服务器,其中包含一个运行方法,该方法将在另一个线程中使用 QtConcurrent::run 运行。

我的第一个问题是:

当我不创建一个不继承自 QTcpServer 且仅使用 QTcpServer 对象的服务器时,我是对的吗?

第二个问题:

在另一个线程中只运行一个方法是错误的吗?因为我已经学会了在 C# 和其他 Qt 示例中这样做,它们将当前对象放入其他线程中。

第三个问题:

为什么我会收到此消息:

QObject:无法为对象创建子对象 位于不同线程中的父级。 (父级是 MyServer(0x1ab1ca0), 父线程是QThread(0x187a840), 当前线程是QThread(0x1acfa90)

当我启动 run 方法时,

。这是源代码:

myserver.h

#ifndef MYSERVER_H
#define MYSERVER_H

#include <QObject>
#include <QtNetwork/QTcpServer>
#include <QtConcurrentRun>
#include <QFuture>
#include "myclienthandle.h"

class MyServer : public QObject
{
    Q_OBJECT
public:
    explicit MyServer(QObject *parent = 0, const QString &ip = "Any", int port = 0);
    explicit MyServer(const MyServer &server);
    ~MyServer();
    QString IP() const;
    void setIP(const QString &ip);
    int Port() const;
    void setPort(int port);
    bool isAlive() const;


private:
    QTcpServer *m_qtcpserListener;
    QFuture<void> m_qftrRun;
    QString *m_qstrIP;
    int m_iPort;
    int m_iClientID;
    bool m_bRun;

    void run();

signals:
    void newConnection(MyClientHandle *clientHandle);

public slots:
    void start();
    void stop();
};

inline QString MyServer::IP() const
{
    return *m_qstrIP;
}

inline void MyServer::setIP(const QString &ip)
{
    m_qstrIP = new QString(ip);
}

inline int MyServer::Port() const
{
    return m_iPort;
}

inline void MyServer::setPort(int port)
{
    m_iPort = port;
}

inline bool MyServer::isAlive() const
{
    return m_bRun;
}

#endif // MYSERVER_H

myserver.cpp

#include "myserver.h"

MyServer::MyServer(QObject *parent, const QString &ip, int port) :
    QObject(parent), m_iClientID(0), m_bRun(false), m_qtcpserListener(0)
{
    setIP(ip);
    setPort(port);
}

MyServer::MyServer(const MyServer &server)
{
    MyServer(server.parent(), server.IP(), server.Port());
}

MyServer::~MyServer()
{
    if (m_qtcpserListener != 0)
        stop();
}

void MyServer::run()
{
    m_qtcpserListener = new QTcpServer(this);

    if (!m_qtcpserListener->listen(QHostAddress(IP()), Port()))
    {
        return;
    }

    while (m_bRun)
    {
        if (m_qtcpserListener->waitForNewConnection(5000))
        {
            QTcpSocket *qtcpsoNextPending = m_qtcpserListener->nextPendingConnection();
            emit newConnection(new MyClientHandle(qtcpsoNextPending));
        }
    }
}

void MyServer::start()
{
    m_bRun = true;
    m_qftrRun = QtConcurrent::run(this, &MyServer::run);
}

void MyServer::stop()
{
    m_bRun = false;
    if (m_qtcpserListener != 0 && m_qtcpserListener->isListening())
    {
        m_qtcpserListener->close();
    }
    m_qftrRun.cancel();
    m_qftrRun.waitForFinished();
}

谢谢您的帮助。

I'm trying to develop a threaded server that contains a run method which is to run in another thread with QtConcurrent::run.

My first question is:

Am I right, when I don't create a server that doesn't inherit from QTcpServer and just uses an object of QTcpServer.

Second question:

Is it wrong to run only one method in a other thread? Because I’ve learned it to do it like this in C# and in other Qt examples they put the current object in a other thread.

Third question:

Why do I get this message:

QObject: Cannot create children for a
parent that is in a different thread.
(Parent is MyServer(0x1ab1ca0),
parent's thread is QThread(0x187a840),
current thread is QThread(0x1acfa90)

When I start the run method.

Here is the source code:

myserver.h

#ifndef MYSERVER_H
#define MYSERVER_H

#include <QObject>
#include <QtNetwork/QTcpServer>
#include <QtConcurrentRun>
#include <QFuture>
#include "myclienthandle.h"

class MyServer : public QObject
{
    Q_OBJECT
public:
    explicit MyServer(QObject *parent = 0, const QString &ip = "Any", int port = 0);
    explicit MyServer(const MyServer &server);
    ~MyServer();
    QString IP() const;
    void setIP(const QString &ip);
    int Port() const;
    void setPort(int port);
    bool isAlive() const;


private:
    QTcpServer *m_qtcpserListener;
    QFuture<void> m_qftrRun;
    QString *m_qstrIP;
    int m_iPort;
    int m_iClientID;
    bool m_bRun;

    void run();

signals:
    void newConnection(MyClientHandle *clientHandle);

public slots:
    void start();
    void stop();
};

inline QString MyServer::IP() const
{
    return *m_qstrIP;
}

inline void MyServer::setIP(const QString &ip)
{
    m_qstrIP = new QString(ip);
}

inline int MyServer::Port() const
{
    return m_iPort;
}

inline void MyServer::setPort(int port)
{
    m_iPort = port;
}

inline bool MyServer::isAlive() const
{
    return m_bRun;
}

#endif // MYSERVER_H

myserver.cpp

#include "myserver.h"

MyServer::MyServer(QObject *parent, const QString &ip, int port) :
    QObject(parent), m_iClientID(0), m_bRun(false), m_qtcpserListener(0)
{
    setIP(ip);
    setPort(port);
}

MyServer::MyServer(const MyServer &server)
{
    MyServer(server.parent(), server.IP(), server.Port());
}

MyServer::~MyServer()
{
    if (m_qtcpserListener != 0)
        stop();
}

void MyServer::run()
{
    m_qtcpserListener = new QTcpServer(this);

    if (!m_qtcpserListener->listen(QHostAddress(IP()), Port()))
    {
        return;
    }

    while (m_bRun)
    {
        if (m_qtcpserListener->waitForNewConnection(5000))
        {
            QTcpSocket *qtcpsoNextPending = m_qtcpserListener->nextPendingConnection();
            emit newConnection(new MyClientHandle(qtcpsoNextPending));
        }
    }
}

void MyServer::start()
{
    m_bRun = true;
    m_qftrRun = QtConcurrent::run(this, &MyServer::run);
}

void MyServer::stop()
{
    m_bRun = false;
    if (m_qtcpserListener != 0 && m_qtcpserListener->isListening())
    {
        m_qtcpserListener->close();
    }
    m_qftrRun.cancel();
    m_qftrRun.waitForFinished();
}

Thank you for your help.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

一指流沙 2024-11-22 18:53:15

您的问题是您正在不同的线程中运行 MyServer::run 函数(通过 QtConcurrent::run,但在 MyServer::run在 Qt 中,在一个线程(并发线程)中创建的对象的父对象不能是另一个线程拥有的对象(无论 的实例是什么线程)。 MyServer 已存在,可能是第一个 如果您超越了这一点

,在与信号对象不同的线程中发出信号也可能会导致删除问题,因为您不应该在与拥有该对象的线程不同的线程中删除 QObject。 -

我的建议是使用 QTcpServer 的内置 在线程机制中。 listen,该函数将返回,然后您可以连接到< code>newConnection() 当有连接挂起时发出通知,而不是等待连接(这可能会让您认为您需要同时运行该函数)。

Your problem is that you are running the MyServer::run function in a different thread (via QtConcurrent::run, but in the MyServer::run function you create a new TcpServer and give it a parent. In Qt, the parent of an object created in one thread (the concurrent one) can't be an object owned by another thread (whatever thread the instance of MyServer is in, probably the first thread).

If you got past that, emitting signals in a different thread than the signaling object can also cause problems. You may also run into problems in deletion, since you shouldn't delete a QObject in a different thread than the one that owns it.

My suggestion is to use QTcpServer's built-in threaded mechanism. When you call listen, the function will return. You could then connect to the newConnection() signal to be notified when there is a connection pending, instead of waiting for a connection (which is what might lead you to think you needed to run the function concurrently).

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文