Skip to content
  • Categories
  • Recent
  • Tags
  • Popular
  • Users
  • Groups
  • Search
  • Get Qt Extensions
  • Unsolved
Collapse
Brand Logo
  1. Home
  2. Qt Development
  3. General and Desktop
  4. [solved]A problem in using QThread
QtWS25 Last Chance

[solved]A problem in using QThread

Scheduled Pinned Locked Moved General and Desktop
5 Posts 3 Posters 2.1k Views
  • Oldest to Newest
  • Newest to Oldest
  • Most Votes
Reply
  • Reply as topic
Log in to reply
This topic has been deleted. Only users with topic management privileges can see it.
  • H Offline
    H Offline
    hyzhappy
    wrote on last edited by
    #1

    I meet an issue "QObject: Cannot create children for a parent that is in a different thread.
    (Parent is QNativeSocketEngine(0x9d85728), parent's thread is QThread(0x9aa77f8), current thread is Downloader(0x9de8700)"
    I write a class called "Downloader", and I wanna it runs in another thread than main thread. Downloader inherit
    from QThread. I overload run() as:
    @
    void Downloader::run(){
    mutex.lock();
    QString file_path = filename;
    QFile file(file_path);
    int i=1;
    int index = file_path.lastIndexOf('.');
    while(file.exists()){
    file_path = file_path.replace(index, 1, QString("(%1).").arg(QString::number(i)));
    file.setFileName(file_path);
    i++;
    }
    if(file.open(QIODevice::WriteOnly)){
    mutex.unlock();
    qint64 msize = 0;
    while(msize<filesize){
    if(socket.waitForReadyRead()){
    QByteArray x=socket.read();
    int len=file.write(x);
    msize += x.count();
    }
    }
    socket.close();
    file.close();
    }
    else{
    mutex.unlock();
    }
    }
    @
    In main thread, I call "Downloader *downloader = new Downloader(); downloader->run(); ",then it report the issue. I want to know what's wrong in my code.
    Thx.

    By the way, Another class called "Uploader" is similar, but It runs normal.
    @
    void Uploader::run(){
    qint64 size=0;
    file->open(QIODevice::ReadOnly);
    while(size < file->size()){
    QByteArray x= file->read(1024);
    size += x.count();
    socket.write(x);
    }
    socket.close();
    file->close();
    }
    @

    I learnt that there are two ways using multithread, inherit QThread or use movetothread then emit a signal to call a slot function in another thread. I try to avoid too many connections between signals and slots, so I choose to inherit QThread.
    But what's wrong if the "socket" is created in main thread. In fact, "socket" is Downloader's member, and it connect to host in constructor.
    @
    Downloader::Downloader(const QString& filename,
    const QString& address,int port,qint64 size, QObject *parent) :
    QThread(parent)
    {
    this->filename = filename;
    this->filesize = size;
    this->socket.connectToHost(address,port);
    }
    @
    Or should I must go in "movetothread" way?
    (My mutex in Downloader is used to mutex file access on the disk, and unlock in file.open() is to make sure the file's been created. )

    1 Reply Last reply
    0
    • sierdzioS Offline
      sierdzioS Offline
      sierdzio
      Moderators
      wrote on last edited by
      #2

      It is recommended not to subclass QThread if it can be avoided (which is in most cases). It is easy to confuse QThread (which is running in the main thread) with the thread (code inside run()).

      The snippet does not show what is "socket" variable. It also does not use "len" variable. You unlock the mutex in both results of "if" - why? You can do it once, before the if. Or use a QMutexLocker. Also, there seems to be no reason to use QMutex in this code at all - you lock it only to modify a couple of local variables, nothing that is shared between threads. So there is no danger of locking here (although I think you are doing this to avoid ceating duplicate files, in such case it may be a good thing indeed).

      You can use QFileInfo instead of QFile. And there is no reason to construct the object, you can use the static QFileInfo::exists() method.

      Now, on to what I suspect: your socket lives in a different thread from run().

      (Z(:^

      1 Reply Last reply
      0
      • SGaistS Offline
        SGaistS Offline
        SGaist
        Lifetime Qt Champion
        wrote on last edited by
        #3

        Hi and welcome to devnet,

        You seem to be using a socket that's been created e.g. in the your Uploader/Downloader contractor. Which means that this socket has thread affinity with the that created your object not the thread that is running run. QThread is not a thread per se but a thread manager.

        Please have a look at QThread's latest "documentation":http://qt-project.org/doc/qt-5/qthread.html so see the various use and technique.

        Interested in AI ? www.idiap.ch
        Please read the Qt Code of Conduct - https://forum.qt.io/topic/113070/qt-code-of-conduct

        1 Reply Last reply
        0
        • H Offline
          H Offline
          hyzhappy
          wrote on last edited by
          #4

          Thanks for your help, the issue had been solved.
          It's like that QTcpSocket couldn't read and create in different Thread, but write could. It may be a mechanism of OS. So I created QTcpsocket and call its read method in the new thread instead.
          @
          if(file.open(QIODevice::WriteOnly)){
          mutex.unlock();
          socket = new QTcpSocket();
          socket->connectToHost(address, port);
          qint64 msize = 0;
          while(msize<filesize){
          if(socket->waitForReadyRead()){
          QByteArray x=socket->read(1024);
          int len=file.write(x);
          msize += x.count();
          }
          }
          socket->close();
          file.close();
          delete socket;
          }
          @

          1 Reply Last reply
          0
          • SGaistS Offline
            SGaistS Offline
            SGaist
            Lifetime Qt Champion
            wrote on last edited by
            #5

            You're welcome !

            Now that you have your thread running, please update the thread title prepending [solved] so other forum users may know a solution has been found :)

            Interested in AI ? www.idiap.ch
            Please read the Qt Code of Conduct - https://forum.qt.io/topic/113070/qt-code-of-conduct

            1 Reply Last reply
            0

            • Login

            • Login or register to search.
            • First post
              Last post
            0
            • Categories
            • Recent
            • Tags
            • Popular
            • Users
            • Groups
            • Search
            • Get Qt Extensions
            • Unsolved