Qt Multithreading synchronization and communication

Source: Internet
Author: User
Tags ming mutex semaphore

Go from Network

1 Multi-thread synchronization

QT offers the following classes to accomplish this: Qmutex, Qmutexlocker, Qsemphore, Qwaitcondition. It may also contain qreadwritelocker, Qreadlocker, Qwritelocker, but Thread SynchronizationThe application is very few, here only to do simple explanation! The Qmutex, Qmutexlockerqmutex class provides a way to protect a critical section code by allowing only one thread to access the critical section code at a time. The Qmutex::lock () function is used to lock the mutex, and if the mutex is unlocked, the current thread catches and locks it immediately, otherwise the current thread is blocked until the thread holding the mutex is unlocked. When the thread calls the lock () function, it holds the mutex until the unlock () operation is called. Qmutex also provides a trylock () function that returns immediately if the mutex is locked. When the problem comes out, if you want to use mutexes in the Stop () function for mutual exclusion, but the unlock () operation is written there? The unlock () operation has to return again, causing the unlock () operation to never execute ... QtProvides the Qmutexlocker class how to simplify the processing of mutex, which takes a Qmutex object as a parameter in the constructor and locks it, unlocks the mutex in the destructor.
BOOL Thread::stop ()
{
Qmutexlocker Locker (&mutex);
m_stop = true;
return m_stop;
}

Qreadwritelocker , Qreadlocker, QwritelockerBelow is a section of the Qreadwritelocker class of objects, read and write the operation of the lock, it is relatively simple, there is no more explanation, see for yourself
 mydata data;  Qreadwritelock  lock  ;           void   Readerthread::run () {...           lock  .lockforread ();           Access_data_without_modifying_it ( &data);          lock  .unlock ();  ...    }  void   Writerthread::run () {...  lock      .lockforwrite ();     Modify_data ( &data);     lock  .unlock (); ...        } 

Qsemphore

QtThe semaphore is provided by the Qsemaphore class, and the semaphore can be understood as an extension of the mutex function, which can only be locked once and the semaphore can be obtained multiple times, which is used to protect a certain amount of the same resource. The acquire (n) function is used to get n resources, and when there are not enough resources, the caller will be blocked until there are enough available resources. The release (n) function is used to dispose of n resources. The Qsemaphore class also provides a Tryacquire (n) function, in which the function returns immediately if there is not enough resources. A typical semaphore application is in two ThreadsA certain amount of data (datasize) is passed between the two ThreadsUse a shared loop cache of a certain size (buffersize).
const int datasize = 100000;
const int buffersize = 4096;
Char Buffer[buffersize];
Producers ThreadsWrites data to the cache until it reaches the end point, and then begins again at the beginning to overwrite the existing data. Consumers ThreadsRead the data generated by the former. Producers, consumer instances in the SyncThere are two requirements, if the producer produces data too quickly, it will overwrite the data that the consumer has not yet read, and if the consumer reads the data too quickly, it will cross the producer and read some junk data. An effective way to solve this problem is to use two semaphores:
Qsemaphore FreeSpace (buffersize);
Qsemaphore usedspace (0);
FreeSpace Semaphore control the producer can populate the cache portion of the data. The Usedspace semaphore controls the areas that consumers can read. The two semaphores are complementary. wherein the FreeSpace semaphore is initialized to buffersize (4096), indicating that at the beginning of the program a buffersize buffer unit can be populated, and the semaphore Usedspace is initialized to 0, indicating that no data is available for reading in the beginning of the program buffer. For this instance, each byte is considered a resource, and the actual application often operates on a larger unit, reducing the overhead associated with using semaphores.
void Producer::run ()  {        for (int0; i < datasize; + +i) {           freespace.acquire ()           ;  " MING " [UINT4];           Usedspace.release ();         }   

In the producer, we start by acquiring a "free" byte. If the cache is filled with data that the consumer has not yet read, the call to acquire () blocks until the consumer has started consuming the data. Once we have acquired this byte, we populate it with random data ("M", "I", "N" or "G") and release the byte as "used", so it can be used by the consumer thread .

void Consumer::run ()    {     for (int0; i < datasize; + +i) {            usedspace.acquire ()          ;  << buffer[i% buffersize];           Freespace.release ();             }           << Endl;    

   int Main ()     {         Producer Producer;         Consumer Consumer;         Producer.start ();         Consumer.start ();         Producer.wait ();         Consumer.wait ();          return 0 ;      
qwaitconditionAnother solution to the problem of producers and consumers is to use qwaitcondition, which allows Thread inWake up other under certain conditions Threads。 where the Wakeone () function randomly wakes up a wait when the condition is met Threads, while the Wakeall () function wakes all waits when the condition is met Threads
The following overrides the producer and consumer instances to Qmutex as a wait condition, Qwaitcondition allows a ThreadsUnder certain conditions to wake up other Threads

   const int datasize = 100000;  
   const int buffersize = 4096;  
   Char Buffer[buffersize];  
   Qwaitcondition Bufferisnotfull;  
   Qwaitcondition Bufferisnotempty;  
   Qmutex Mutex;  
   int usedspace = 0;

Outside of the cache, we declare two qwaitcondition, a Qmutex, and a variable that stores the number of "used" bytes in the cache.
   voidProducer::run () { for(inti =0; i < datasize; ++i) {mutex.Lock(); if(Usedspace = =buffersize) bufferisnotfull.wait (&mutex); Buffer[i% buffersize] ="MING"[UINT(rand ())%4]; ++Usedspace;          Bufferisnotempty.wakeall ();          Mutex.unlock (); }     }
In the producer, we start by checking whether the cache is full. If it is full, we wait for the "cache is not full" condition. When this condition is met, we write a byte to the cache, increase the usedspace, and wake any wait for this "cache is not blank" condition to become true Threads。 All statements in the For loop need to be secured with a mutex to protect the atomicity of its operation.
BOOL Wait (Qmutex * Mutex, unsigned long  time = Ulong_max );
This function makes the following description, the function unlocks the mutex and waits here, it has two parameters, the first parameter is a locked mutex, the second parameter is the wait time. The wait () function returns immediately if the mutex as the first parameter is in the case that the call is not locked or a recursive lock occurs. Called by the Wait () operation. ThreadsMakes the mutex as a parameter become locked before the call, and then itself is blocked into a wait state until the following conditions are met: other ThreadsThe Wakeone () or Wakeall () function is called, in which case a value of "true" is returned. The second parameter time time-out (in milliseconds), the default is Ulong_max, which means that never times out, in which case a value of "false" is returned. The wait () function returns the mutex parameter to a locked state before returning, guaranteeing a principled conversion from the lock state to the wait state.
void Consumer::run ()   {       Forever {           mutex. } Lock ();            if 0 )               bufferisnotempty.wait (&Mutex);            << buffer[i% buffersize];            --Usedspace;           Bufferisnotfull.wakeall ();        Mutex.unlock ();    }     << Endl;    }
Consumers do the opposite of producers, he waits for "cache is not blank" condition and wakes up any waiting "cache is not full" condition Threads。 The main () function is basically the same as above, and this is no longer a lot to say. The static function CurrentThread () in the Qthread class can return the current ThreadsOf ThreadsId. In the X11 environment, this ID is a unsigned long type value. Self-summary: Atomic typeQatomicintQatomicpointer 2. Multithreading communication A.  The global variable is shared memory B.  Pipe C. Signal Slot 3. Multi-process communication signal slot socket file mapping

Qt Multithreading synchronization and communication

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.