Linux Qt using multi-threaded POSIX condition variable, mutex (amount)

Today the League building, but also to write the article. Drink good wine, write the text the United States, the road side to my generation all-rounder programmer. quack

 

Before've been watching POSIX multithreaded programming, combined with last weekend's own understanding, based on a written Qt example of a condition variable thread synchronization. Therefore to share with everyone, and hope to share with everyone.

 

Mentioned thread, if the UI program, there is always time-consuming, and some operations together. Qt processing consuming operations are usually two ways, one is a time-consuming operation on the thread; the other is to use the QApplication :: the processEvents () , to prevent blocking the UI . From a more general point of view, I am more inclined to the thread, but for many beginners, a thread or a certain degree of difficulty. For example, the need to provide for the protection of data shared between threads using mutex synchronization, use condition variables, use read-write lock synchronization; various synchronous manner under what circumstances, is not much at the start of multi-threaded programming use, not keenly aware of these issues, and later wrote the program a little more slowly come into contact with some of the things multithreading, and they can also learn the relevant knowledge, and use the actual program. Well, here with a practical example of the background, to illustrate the Linux POSIX some of the features of multithreading.

 

Environmental program: Ubuntu 14.04 , Qt 5.5.1 , Posix multithreading (C usage )

Simply put down what I use here Linux C multithreading, because Qt multi-programmed for the termination of some threads of ambiguity is not clear, and a thread resources after the termination can not be cleaned, so I chose a relatively low-level Some usage, I will have the opportunity to add cancel threads and thread exits the operation.

 

I set myself a scene like this, the UI main thread queue interface to manually shared between a thread through push data, and the other is to open a thread has been while the pop data, which can be considered a variant of producer and a consumer model it.

As for the condition variable, mutex ( ie mutex ) initialization not go into detail here, indicating only some relatively important place.

 

1. UI in the queue to push data ( the producer in the production )

This is a function of the groove, when lineEdit after the carriage return, the slot function is triggered, since the queue is among threads shared data, the use of a protection mutex, i.e. during operation of the groove data if other threads that want to manipulate the data, the other threads will be blocked, that access has been a mutex locking thread will be blocked.

 

void Widget::on_le_writeNum_returnPressed()
{
    int status;

    status = pthread_mutex_lock (&mp_processThread->m_structCondition.mutex);
    if (status != 0)
        err_abort (status, "Lock mutex");

    QString num = ui->le_writeNum->text();
    mp_processThread->queuePushData(num.toInt());

    status = pthread_cond_signal (&mp_processThread->m_structCondition.cond);
//    status = pthread_cond_broadcast( &mp_processThread->m_structCondition.cond);
    if (status != 0)
        err_abort (status, "Signal condition");

    status = pthread_mutex_unlock (&mp_processThread->m_structCondition.mutex);
    if (status != 0)
        err_abort (status, "Unlock mutex");
}

 

  

2. The  consumer thread pop data

The thread using Qt 's moveToThread thread method created here noted that the entire class will run in the new thread. The grooves function as the thread start signal (Start ()) after the transmitter has been performed while loop. First mutex lock, after the determination predicate state, if the queue is empty, waiting condition variable. While waiting condition variable pthread_cond_wait () will automatically release the mutex so that other threads to be able to share operational data. After waking up from waiting condition variable, get the mutex again, to operate the shared data. After sharing data is done, again release the mutex. This is what we use to wait for a condition variable operating procedures, if we do not use a condition variable wait will be like?

 

 

void ProcessThread::slot_processData()
{
    int status;

    while(!mb_stopThread)
    {
        status = pthread_mutex_lock (&m_structCondition.mutex);
        if (status != 0)
            err_abort (status, "Lock mutex");

        while(m_queue.empty())   //if queue is empty, wait contion
        {
//使用条件变量等待
            status = pthread_cond_wait(&m_structCondition.cond,
                                       &m_structCondition.mutex); 
//            qDebug() << "pthread_cond_wait is block func!";

            if (status != 0)
            {
                err_abort (status, "Wait on cond faild");
            }
        }

        while(!m_queue.empty())
        {
            qDebug() << "queue mem is" << m_queue.back();

            m_queue.pop();
        }

        status = pthread_mutex_unlock (&m_structCondition.mutex);
        if (status != 0)
            err_abort (status, "Unlock mutex");

    }

}

 

  

3.  do not use a condition variable wait

① do not use a condition variable wait

If you do not use the condition variable waiting, almost all consumer threads executing in a great time while (1) infinite loop, which is occupied CPU resources in ubuntu , the use htop see the effects of the following:

屏蔽status = pthread_cond_wait(&m_structCondition.cond,

&m_structCondition.mutex);

We see, then CPU is running at full capacity, which of course is not a program should have a normal state.

 

② use condition variable results

 

At this point we see the CPU occupancy rate is very low, and this is one of the reasons why the use of variable conditions, so that the thread does not satisfy the conditions of suspended, rather than wasting CPU resources. Condition variables allow exchange mechanism between queue status information using the thread queue. So when when we have not mastered the use of thread condition variables, and this is the case, how to do it? Simple, add a 5ms delay can, 5ms for us a very short time is very short, but the computer is concerned, it has been quite a long time.

 

Finally, when we turn off the UI window appears, there will be such a message:

QThread: Destroyed while thread is still running

Was destroyed when the thread is running, the next we would say, and that is how to exit a thread, the thread termination and cancel threads and other operations.

Welcome to share with everyone!

 

If reproduced, please indicate the source is prohibited commercial use, thanks to cooperation.

 

Guess you like

Origin www.cnblogs.com/d-h-/p/11286171.html