Summary of QT multithreading programming (ii)--qmutex

Source: Internet
Author: User

The Qmutex class provides a sequential access between threads.

The purpose of Qmutex is to protect an object, data structure, or code snippet, so that only one thread can access it at the same time. (in Java terminology, it is similar to the Sync keyword "synchronized"). For example, here's a way to print two messages to the user:

[CPP]View PlainCopy
    1. void SomeMethod ()
    2. {
    3. Qdebug ("Hello");
    4. Qdebug ("World");
    5. }

If this method is called in two threads at the same time, the order of the results will be:

  Hello  Hello  world    

If you are using a mutex:

[CPP]View PlainCopy
    1. Qmutex Mutex;
    2. void SomeMethod ()
    3. {
    4. Mutex.lock ();
    5. Qdebug ("Hello");
    6. Qdebug ("World");
    7. Mutex.unlock ();
    8. }

In Java terminology, this code should be:

[CPP]View PlainCopy
    1. void SomeMethod ()
    2. {
    3. Synchronized {
    4. Qdebug ("Hello");
    5. Qdebug ("World");
    6. }
    7. }

Then only one thread at a time can run SomeMethod and the order of the messages is always correct. This is, of course, a very simple example, but it applies to anything that needs to happen at a specific frequency.

But you call lock () in one thread, and the other thread will attempt to call Lock () at the same location to block, knowing that the other thread will get the lock after the thread calls unlock (). A non-blocking selection of lock () is Trylock ().

Experimental section:

Scenario One:

[CPP]View PlainCopy
  1. #include <QtCore/QCoreApplication>
  2. #include <Qthread>
  3. #include <QTextStream>
  4. Class Mythreada: Public qthread {
  5. Public
  6. Virtual void run ();
  7. };
  8. Class mythreadb: Public qthread {
  9. Public
  10. Virtual void run ();
  11. };
  12. int number=6;
  13. void Mythreada::run () {
  14. Number *= 5;
  15. Number/= 4;
  16. }
  17. void Mythreadb::run () {
  18. Number *= 3;
  19. Number/= 2;
  20. }
  21. int main (int argc, char *argv[])
  22. {
  23. Qcoreapplication app (argc, argv);
  24. Mythreada A;
  25. MYTHREADB b;
  26. A.run ();
  27. B.run ();
  28. A.terminate ();
  29. B.terminate ();
  30. Qtextstream out (stdout);
  31. out<<number;
  32. return App.exec ();
  33. }

The above code, very simple, wrote two threads, covering the Qthread pure virtual function run (), the two refactoring of the Run method is the global variable number operation,

The two methods are called sequentially in the main function, and after A.run () is executed, number is 7,b.run () after 10.

Scenario Two:

[CPP]View PlainCopy
  1. #include <QtCore/QCoreApplication>
  2. #include <Qthread>
  3. #include <QTextStream>
  4. Class Mythreada: Public qthread {
  5. Public
  6. Virtual void run ();
  7. };
  8. Class mythreadb: Public qthread {
  9. Public
  10. Virtual void run ();
  11. };
  12. int number=6;
  13. void Mythreada::run () {
  14. Number *= 5;
  15. Sleep (1);
  16. Number/= 4;
  17. }
  18. void Mythreadb::run () {
  19. Number *= 3;
  20. Sleep (1);
  21. Number/= 2;
  22. }
  23. int main (int argc, char *argv[])
  24. {
  25. Qcoreapplication app (argc, argv);
  26. Mythreada A;
  27. MYTHREADB b;
  28. A.start ();
  29. B.start ();
  30. A.wait ();
  31. B.wait ();
  32. Qtextstream out (stdout);
  33. out<<number;
  34. return App.exec ();
  35. }

Operation Result:

number=11;

Using the Qthread method Start () is the same as opening two threads, it is worth noting that the wait () function, can not wait for itself, this is used to interact with multiple threads, so can not be used as sleep (). This function blocks the main thread when it is called in the main thread. If you want to let the child thread pause externally, the best way is to set a flag in the child thread, change the flag in the main thread, and judge in the run function of the child thread, by calling its protection function sleep () to achieve the purpose of the pause.

To view the source code, you have a clear concept:

[CPP]View PlainCopy
  1. BOOL Qthread::wait (unsigned long time)
  2. {
  3. Q_d (Qthread);
  4. Qmutexlocker Locker (&d->mutex);
  5. if (D->id = = GetCurrentThreadID ()) {
  6. Qwarning ("Qthread::wait:thread tried to wait on itself"); //When it is itself, return false directly
  7. return false;
  8. }
  9. if (d->finished | |!d->running) //The thread associated with this thread object has ended execution (for example, returned from the Run function). Returns true if the thread ends.  Returns true if the thread has not started yet.
  10. return true;
  11. ++d->waiters;
  12. Locker.mutex ()->unlock ();
  13. BOOL ret = false;
  14. switch (WaitForSingleObject (D->handle, Time)) { //Call Win's object handler function
  15. Case WAIT_OBJECT_0: //Core object is activated, waiting for success
  16. ret = true;
  17. Break ;
  18. Case wait_failed:
  19. Qerrnowarning ("Qthread::wait:thread wait Failure");
  20. Break ;
  21. Case wait_abandoned:
  22. Case Wait_timeout:
  23. Default:
  24. Break ;
  25. }
  26. Locker.mutex ()->lock ();
  27. --d->waiters;
  28. if (ret &&!d->finished) { //Although the response was successful, but the associated object did not end execution
  29. //thread was terminated by someone else
  30. d->terminated = true;
  31. Qthreadprivate::finish (This, false);
  32. }
  33. if (d->finished &&!d->waiters) { //The associated object execution ends and the wait number is zero, the handle is closed.
  34. CloseHandle (D->handle);
  35. D->handle = 0;
  36. }
  37. return ret;
  38. }



Scenario Three: (Mutex effect)

[CPP]View PlainCopy
  1. #include <QtCore/QCoreApplication>
  2. #include <Qthread>
  3. #include <QTextStream>
  4. #include <QMutex>
  5. Class Mythreada: Public qthread {
  6. Public
  7. Virtual void run ();
  8. };
  9. Class mythreadb: Public qthread {
  10. Public
  11. Virtual void run ();
  12. };
  13. Qmutex Mutex;
  14. int number=6;
  15. void Mythreada::run () {
  16. Mutex.lock ();
  17. Number *= 5;
  18. Sleep (1);
  19. Number/= 4;
  20. Mutex.unlock ();
  21. }
  22. void Mythreadb::run () {
  23. Mutex.lock ();
  24. Number *= 3;
  25. Sleep (1);
  26. Number/= 2;
  27. Mutex.unlock ();
  28. }
  29. int main (int argc, char *argv[])
  30. {
  31. Qcoreapplication app (argc, argv);
  32. Mythreada A;
  33. MYTHREADB b;
  34. A.start ();
  35. B.start ();
  36. A.wait ();
  37. B.wait ();
  38. Qtextstream out (stdout);
  39. out<<number;
  40. return App.exec ();
  41. }


Operation Result:

number=10;

The experimental results show that QMUTEX protects the global variables, and only one thread can access it at the same time.

Only one mention is the use of Trylock (), if the above code is changed to Mutex.trylock (), then the execution result may be 11, because it is trying to lock the mutex. If the lock is obtained, the function returns True. If the mutex is already locked by another process, the function returns false instead of waiting until the lock is available.

and cannot add the sleep () function, otherwise prompt "A mutex must be unlocked in the same thread that locked it." Run error.

http://blog.csdn.net/mznewfacer/article/details/6966752

Summary of QT multithreading programming (ii)--qmutex

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.