How to terminate QThread correctly?



  • I have 2 class inheriting from QThread, their run() is like:

    void UdpRcv::run()
    {
        while(1){
            recvfrom(sockfd, buf, sizeof(buf), 0, NULL, NULL);
        }
    }
    
    void UdpSnd::run()
    {
        while(1){
            sendto(sockfd, buf, payload_len, 0, (const struct sockaddr *)&v6, sizeof(v6));
        }
    }
    

    I create and run several instances depends on UI setting. They run as expected.
    But when I want to stop them, I get "terminate called without an active exception" randomly.

    Here is how I start/stop them:

    void SgwWindow::debug_udp_start()
    {
        debug_udp_stop();
    
        int cnt = ui->debug_udp_rcv->value();
        for(;cnt>0;--cnt){
            UdpRcv *r = new UdpRcv(this);
            debug_udp_rcv_list.append(r);
            r->start();
        }
    
        cnt = ui->debug_udp_snd->value();
        for(;cnt>0;--cnt){
            UdpSnd *s = new UdpSnd(this);
            debug_udp_snd_list.append(s);
            s->start();
        }
    
    }
    void SgwWindow::debug_udp_stop()
    {
        foreach(UdpRcv *r, debug_udp_rcv_list){
            r->terminate();
            r->wait();
            delete r;
        }
        debug_udp_rcv_list.clear();
        foreach (UdpSnd *s, debug_udp_snd_list) {
            s->terminate();
            s->wait();
            delete s;
        }
        debug_udp_snd_list.clear();
    }
    

  • Qt Champions 2017

    Because you don't terminate threads, you tell them to quit. Terminate is for those rare exceptions that you must close a thread in the middle of work without any regard for what it's doing (e.g. handling SIGSERV or something similar), it is most certainly not for regular thread closing. Anyway, since you are not using event loops you need to handle the quitting yourself.
    Take a look at QThread::isInterruptionRequested() and QThread::requestInterruption(). It'd translate to something like:

    void UdpSnd::run()
    {
        while (!isInterruptionRequested())
        {
            // Read data or w/e
        }
    }
    
    void SgwWindow::debug_udp_stop()
    {
        for (UdpRcv *r : debug_udp_rcv_list)  {
            r->requestInterruption();
            r->wait();
            delete r;
        }
    }
    

    If sendto or recvfrom block however (which is rather normal behaviour for recvfrom) then this doesn't work that well.

    On a related note, did you find QTcpSocket and QUdpSocket not versatile enough for your problem?



  • @kshegunov
    I have another question now,
    if I do a malloc in thread, and force terminat it before freeing the memory, will it cause memory leak?

    Thanks!


  • Qt Champions 2017

    @Mr-Pang said in How to terminate QThread correctly?:

    I have another question now,
    if I do a malloc in thread, and force terminat it before freeing the memory, will it cause memory leak?

    Yes.


Log in to reply
 

Looks like your connection to Qt Forum was lost, please wait while we try to reconnect.