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. Consecutive emiting signal not handled by different thread
Forum Updated to NodeBB v4.3 + New Features

Consecutive emiting signal not handled by different thread

Scheduled Pinned Locked Moved General and Desktop
5 Posts 4 Posters 1.5k Views 1 Watching
  • 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.
  • E Offline
    E Offline
    ermanuret
    wrote on last edited by
    #1

    Hi.

    I have tied to build multi thread GUI app with TCP communication. This GUI sends and receives data from embedded sytem.

    in .h:

    @
    public:
    explicit MainWindow(QWidget *parent = 0);
    ~MainWindow();

    tcp_worker *worker_1;
    tcp_worker *worker_2;
    

    private:
    Ui::MainWindow *ui;

    QTimer *timer;
    
    QThread *thread_1;
    QThread *thread_2;  
    

    @

    in cpp:

    @
    thread_1 = new QThread;
    thread_2 = new QThread;

    worker_1 = new tcp_worker;
    worker_2 = new tcp_worker;

    // Some signal slot connections in there

    worker_1->moveToThread(thread_1);
    worker_2->moveToThread(thread_2);

    thread_1->start();
    thread_2->start();
    @

    Everything goes perfect up to this point. I can receve and send signal to worker class to organize TCP communication. When I need to emit consecutive emit signal in pushbutton click event, I see that only one emit signal triger the connected slot. I can only overcome this with using empty loop between two emit signal statement. I thing this is required because of tcp_thread to goes event loop after process the emmited signal.

    According to my signal slot knowledge, consecutive signals added to evet queue and it will process when the thread reach event loop. I have tried queued and blocking queued connection types as well. How can I overcome that problem without use dummy loop?

    Thanks for your help.

    example code:

    @
    void MainWindow::on_opt_button_clicked()
    {
    emit request_data_front(chanel_data_type);
    emit request_data_rear(chanel_data_type);

    int k = 0;
    for(int i=0; i<6000000; i++)
    {
        k += 1;
    }
    emit request_data_front(chanel_number_front);
    emit request_data_rear(chanel_number_rear);
    

    }
    @

    1 Reply Last reply
    0
    • C Offline
      C Offline
      ckakman
      wrote on last edited by
      #2

      Hi,

      First of all check the QThread documentation. It has several static sleep methods.

      I don't see any issues in the code you have shown. You should get each of your slots called twice with or without the busy-waiting for loop.

      It would help if you prepared a sample project reproducing your issue and uploaded it somewhere.

      1 Reply Last reply
      0
      • dheerendraD Offline
        dheerendraD Offline
        dheerendra
        Qt Champions 2022
        wrote on last edited by
        #3

        Hope you are connecting slots with appropriate signals.what is the connect statement. Which object you are connecting ? I suspect some issue with connect statement and destination object.

        Dheerendra
        @Community Service
        Certified Qt Specialist
        http://www.pthinks.com

        1 Reply Last reply
        0
        • E Offline
          E Offline
          ermanuret
          wrote on last edited by
          #4

          Thanks for reply.

          It is hard to imagine the structure when you move the object to created thread. I thing object and thread creation, signal connection, moving to thread and starting thread order is correct. I suspact first connection from thread to worker.

          On the other hand, in my situation, when I close the GUI thread, worker thread should be automatically closed, but its not. I am sanding some periodic TCP packets, and it continue to send it after close. I thing it is related to TCP socket structure.

          Here is my connect statements related to this subject:

          @
          // For tcp socket creation (initial statements)
          connect(thread_1, SIGNAL(started()), worker_1, SLOT(run()));
          connect(thread_2, SIGNAL(started()), worker_2, SLOT(run()));

          // For connecting specified ip-port
          connect(this, SIGNAL(connect_to_card()), worker_1, SLOT(connect_to_card()));
          connect(this, SIGNAL(connect_to_card()), worker_2, SLOT(connect_to_card()));

          // To see coonection status in textbox
          connect(worker_1, SIGNAL(set_status(QString)), this, SLOT(write_status(QString)));
          connect(worker_2, SIGNAL(set_status(QString)), this, SLOT(write_status(QString)));

          // To plot incoming ByteArray
          connect(worker_1, SIGNAL(read_data(QByteArray, QString)), this, SLOT(plot_data_from_card(QByteArray, QString)), Qt::QueuedConnection);
          connect(worker_2, SIGNAL(read_data(QByteArray, QString)), this, SLOT(plot_data_from_card(QByteArray, QString)), Qt::QueuedConnection);

          // To send command from TCP
          connect(this, SIGNAL(request_data_front(QByteArray)), worker_1, SLOT(request_data(QByteArray)), Qt::QueuedConnection);
          connect(this, SIGNAL(request_data_rear(QByteArray)), worker_2, SLOT(request_data(QByteArray)), Qt::QueuedConnection);

          // internal timer connection
          connect(timer, SIGNAL(timeout()), this, SLOT(timeout()));

          // Set start flag in workers
          connect(this, SIGNAL(start()), worker_1, SLOT(set_start()));
          connect(this, SIGNAL(start()), worker_2, SLOT(set_start()));

          // Close workers
          connect(ui->close_button, SIGNAL(clicked()), worker_1, SLOT(close()));
          connect(ui->close_button, SIGNAL(clicked()), worker_2, SLOT(close()));
          connect(ui->close_button, SIGNAL(clicked()), this, SLOT(close()));

          worker_1->moveToThread(thread_1);
          worker_2->moveToThread(thread_2);
          
          thread_1->start();
          thread_2->start();
          

          @

          1 Reply Last reply
          0
          • R Offline
            R Offline
            Resurrection
            wrote on last edited by
            #5

            Tips and suggestions:

            1. Do not put connection specifiers in your connects. Unless it is necessary (and there are few cases when it is like if you WANT different than default behaviour) you should trust qt to choose correctly.

            2. If you are using Qt 5 switch to the new syntax. It looks clearer and is checked and decided during compile time.

            3. Connect QThread::finished() to its deleteLater() and to its worker's deleteLater() and do NOT parent either:

            @
            connect(thread_1, &QThread::finished, thread_1, &QThread::deleteLater);
            connect(thread_1, &QThread::finished, worker_1, &tcp_worker::deleteLater);
            @

            1. Move this bit to the beginning BEFORE your connections:

            @
            worker_1->moveToThread(thread_1);
            worker_2->moveToThread(thread_2);
            @

            It will make sure that Qt will make the connections correctly because I am not all too sure that they work correctly after you moved the object to another thread. They should but better be on a safe side.

            Secrets are power.

            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