The QT program exits and still accounts for the process

problem situation

The appearance of the program when it is running:
insert image description here
the appearance of the program when it exits:
it ran into the background process:
the program exited, but checked in the task manager, it was transferred from the process to the background process.
What should I do about this kind of problem? In the code, everything that should be released has also been released. Why does this problem occur?
The process in the background sometimes occupies some cpu, which means that it is indeed running and doing something.
This first doubts whether it is a thread problem?

problem analysis

1. Is the thread destructed?

Form's destructor:

MainWindow::~MainWindow()
{
    
    
    if(nullptr != m_pCmdThread)
    {
    
    
        m_pCmdThread->deleteLater();
        delete m_pCmdThread;
    }

Thread's destructor:

CmdThread::~CmdThread()
{
    
    
    quit();
    wait();
}

Looks normal, what's the problem?
May be quit(), wait()

quit()
告诉线程的事件循环以return 0(成功)退出。 相当于调用QThread :: exit(0)。如果线程没有事件循环,这个函数什么也不做。
wait()
阻塞线程,直到满足以下任一条件:
与此QThread对象关联的线程已经完成执行(即从run()返回)。 如果线程完成,该函数将返回true。 如果线程尚未启动,它也返回true。
时间毫秒已经过去了。 如果时间是ULONG_MAX(默认值),那么等待永远不会超时(线程必须从run()返回)。 如果等待超时,此函数将返回false。

The very key explanation here is quit(), quit(), not the thread exit, but the thread event loop exit, if it is an inherited QThread, then, the run method is implemented by itself, and the exec() method is not called in it, then This one thread has no event loop, which must be clear.
Without an event loop, the infinite loop of the run method cannot exit. My code is written like this:

void CmdThread::run()
{
    
    
    qDebug("enter function CmdThread::run");
    m_pCmdService = new CmdService();
    QString strMessage;
    while(true)
    {
    
    
        switch (this->m_currentState)
        {
    
    
        case INIT_PORT:
        case OPEN_PORT:
            if(!m_pCmdService->openPort(*this->m_pBoardInfoDomain))
            {
    
    
                strMessage = QString::asprintf("串口%s连接失败", this->m_pBoardInfoDomain->serialName.c_str());
                emit sendMessage(1, strMessage);
                return;
            }

Obviously, there is no event loop. In this way, the thread is still running. There are many ways to solve this situation. The purpose is to exit this while loop. In fact, it can also be said that there is no suitable method. Quit the running thread, which is dangerous if forced to quit.
To be more formal, use the officially recommended method as follows:

void CmdThread::run()
{
    
    
    qDebug("enter function CmdThread::run");
    m_pCmdService = new CmdService();
    QString strMessage;
    while(true)
    {
    
    
     if(QThread::currentThread()->isInterruptionRequested())
        {
    
    
            break;
        }
        switch (this->m_currentState)
        {
    
    
        case INIT_PORT:
        case OPEN_PORT:
            if(!m_pCmdService->openPort(*this->m_pBoardInfoDomain))
            {
    
    
                strMessage = QString::asprintf("串口%s连接失败", this->m_pBoardInfoDomain->serialName.c_str());
                emit sendMessage(1, strMessage);
                return;
            }

The triggered events are as follows:

CmdThread::~CmdThread()
{
    
    
    requestInterruption();
    quit();
    wait();
}

It is to stop the thread when it is destroyed.
In this way, after testing again, it is found that after closing the form, the background process will no longer exist, which solves this problem. The key points of this problem are: 1. The understanding of the quit and exit functions, which
is the exit thread event , The run method that will not exit the thread
2. The exit of the thread can only be realized by writing the code myself. There is no other way. Exiting in the destructor is a good method.
Returns true if a task that should be stopped is running on this thread. requestInterruption() can request an interrupt.
This feature can be used to make long-running tasks interrupt cleanly. It is recommended to do this periodically in long-running functions. Be careful not to call it too often to keep the overhead low.
Finally, a picture to illustrate the situation:
insert image description here

Guess you like

Origin blog.csdn.net/maokexu123/article/details/130098867