C++ QT запуск функции класса в отдельном потоке

Всем привет. Не так давно начал программировать на Си++. У меня есть класс Joint_S1i и мне нужно запустить в отдельном потоке его функцию void Joint_S1i::runBufferController(). В документации QT к потокам в примере создается отдельный класс, который перемещается в отдельный поток через moveToThread, но я хочу просто запустить функцию уже созданного класса в потоке. Что я пробовал:

1 moveToThread

m_thread = new QThread();
moveToThread(m_thread);
connect(m_thread, &QThread::started, this, &Joint_S1i::runBufferController);
m_thread->start();

2 QtConcurrent

QtConcurrent::run(this, &Joint_S1i::runBufferController);

Когда запускаю программу при обоих вариантах приложение падает. Падает именно на запуске потоков. В дебаггере вижу вот такие сообщения

RTTI symbol not found for class 'QBufferPrivate'
RTTI symbol not found for class 'QBufferPrivate'
RTTI symbol not found for class 'QBufferPrivate'
RTTI symbol not found for class 'QBufferPrivate'
RTTI symbol not found for class 'QBufferPrivate'
RTTI symbol not found for class 'QBufferPrivate'
RTTI symbol not found for class 'QBufferPrivate'
RTTI symbol not found for class 'QThreadPool'
RTTI symbol not found for class 'QThreadPool'
RTTI symbol not found for class 'QThreadPool'
RTTI symbol not found for class 'QThreadPool'
RTTI symbol not found for class 'QThreadPool'
RTTI symbol not found for class 'QThreadPool'
RTTI symbol not found for class 'QThreadPool'

.pro

QT -= gui
QT += core network concurrent

CONFIG += c++11 console
CONFIG -= app_bundle

DEFINES += QT_DEPRECATED_WARNINGS

SOURCES += \
        main.cpp \
    datatransmissionchannel.cpp \
    joint_s1i.cpp

qnx: target.path = /tmp/$${TARGET}/bin
else: unix:!android: target.path = /opt/$${TARGET}/bin
!isEmpty(target.path): INSTALLS += target

HEADERS += \
    datatransmissionchannel.h \
    joint_s1i.h

datatransmissionchannel.h

#include <QObject>
#include <QTcpServer>
#include <QTcpSocket>
#include <QThread>
#include <QBuffer>

class DataTransmissionChannel : public QObject
{
    Q_OBJECT
public:
    explicit DataTransmissionChannel(const quint16 &portIn,
                                     const quint16 &portOut,
                                     const QHostAddress &host = QHostAddress::LocalHost,
                                     QObject *parent = nullptr);
    void runBufferController();

protected:
    QTcpServer *m_tcpServerIn = nullptr;
    QTcpServer *m_tcpServerOut = nullptr;
    QTcpSocket *m_tcpClientIn = nullptr;
    QTcpSocket *m_tcpClientOut = nullptr;
    quint16 m_portIn;
    quint16 m_portOut;
    QHostAddress m_host;
    bool m_opened;
    QBuffer m_buffer;
    qint64 m_maxBufferSize = 10000000;
};

datatransmissionchannel.cpp

#include "datatransmissionchannel.h"

DataTransmissionChannel::DataTransmissionChannel(
        const quint16 &portIn,
        const quint16 &portOut,
        const QHostAddress &host,
        QObject *parent) : QObject(parent)
{
    m_host = host;
    m_portIn = portIn;
    m_portOut = portOut;
    m_tcpServerIn = new QTcpServer(this);
    m_tcpServerOut = new QTcpServer(this);
    m_tcpServerIn->listen(m_host, m_portIn);
    m_tcpServerOut->listen(m_host, portOut);
}

void DataTransmissionChannel::runBufferController()
{
    while(m_opened) {
        bool emptyBuffer = false;
        if (m_buffer.size() < m_maxBufferSize * 0.2)
            emptyBuffer = true;
        if (m_buffer.size() > m_maxBufferSize * 0.8)
            emptyBuffer = false;
        if (emptyBuffer && m_tcpClientIn)
            m_tcpClientIn->write("Need data");
        if (m_buffer.size() == 0)
            this->thread()->sleep(1);
    }
}

joint_s1i.h

#include "datatransmissionchannel.h"

class Joint_S1I : public DataTransmissionChannel
{
    Q_OBJECT
public:
    explicit Joint_S1I(const quint16 &portIn = 42599,
                       const quint16 &portOut = 42600,
                       const QHostAddress &host = QHostAddress::LocalHost,
                       QObject *parent = nullptr);
    void run();
};

joint_s1i.cpp

#include "joint_s1i.h"
#include "QtConcurrent"


Joint_S1I::Joint_S1I(const quint16 &portIn,
                     const quint16 &portOut,
                     const QHostAddress &host,
                     QObject *parent) :
    DataTransmissionChannel(portIn, portOut, host, parent)
{
    run();
}

void Joint_S1I::run()
{
    m_opened = true;
    m_buffer.open(QIODevice::ReadWrite);
    QtConcurrent::run(this, static_cast<void(Joint_S1I::*)()>(&Joint_S1I::runBufferController));
    

main.cpp

#include <QCoreApplication>
#include "joint_s1i.h"

int main(int argc, char *argv[])
{
    QCoreApplication a(argc, argv);

    Joint_S1I joint_S1I;

    return a.exec();
}

Ответы (1 шт):

Автор решения: Петр

Как выяснилось тут проблема не в запуске функции в отдельном потоке. Поток запускается. Проблема в моем буффере. Я использую класс QBuffer, который не потокобезопасный. Сначала я его открывал буффер для чтения/записи, а потом пытался запустить поток, который должен был получать доступ к тому же объекту QBuffer. Проблема была именно в этом. Попробовал запустить поток без открытия буффера и все заработало. Вот рабочий вариант:

QtConcurrent::run(this, static_cast<void(Joint_S1I::*)()>(&Joint_S1I::runBufferController));
→ Ссылка