SlideShare a Scribd company logo
Qt Concurrency 
Ynon Perek
Agenda 
• Doing things simultaneously 
• Using the event loop 
• Using threads 
• Using QtConcurrent algorithms
The Event Loop 
MainLoop 
event 1 
Handler Handler Handler
You’re Already Doing It 
• Network code runs in parallel 
• Timers
Unfortunately … 
• DB queries block 
• Disk operations block 
• CPU operations block
Latency Is The Enemy
What We Need 
• Run something “in the background” 
• A single task 
• A worker thread 
• A full algorithm 
• Another application
Single Task 
QThread 
QThreadPool 
QRunnable 
Thread Synchronization
Threads Theory 
• Define tasks by extending QRunnable 
• Use QThreadsPool to run them
Demo Runnable 
class MyTask : public QRunnable 
{ 
virtual void run() 
{ 
for ( int i=0; i < 10; i++ ) 
{ 
qDebug() << "[" << 
QThread::currentThreadId() << 
"]" << 
" " << 
i; 
} 
} 
};
Using The Thread Pool 
QCoreApplication a(argc, argv); 
MyTask *t1 = new MyTask; 
QThreadPool p; 
p.start(t1); 
p.waitForDone();
Thread Pool Notes 
• start() takes ownership of the runnable. 
It will be deleted when done 
• Number of threads matches number of 
CPU cores 
• waitForDone() stops the event loop. Be 
careful with that one
Yielding 
• If you feel your thread has worked hard 
enough, rest with: 
QThread::yieldCurrentThread();
Sharing 
• Cool in real life 
• Uncool for threads
Sharing Problems 
• Shared resources can 
be manipulated from 
other threads 
• Even when you’re in 
the middle
Sharing Problems 
Can you use the code below from multiple threads ? 
class Counter 
{ 
public: 
Counter() { n = 0; } 
void increment() { ++n; } 
void decrement() { --n; } 
int value() const { return n; } 
private: 
int n; 
}; 
Why ?
Sharing Problems 
• Most Qt and C++ code is re-entrant 
• It means you can’t access same instance 
from different threads at the same time
Quiz 
• Assume 
m_text is a 
QStringList 
• Can you use 
the code from 
multiple 
threads ? Why ? 
virtual void run() 
{ 
m_text.append(m_a); 
for ( int i=0; i < 100; i++ ) 
{ 
if ( m_text.last() == m_a ) 
{ 
m_text.append(m_b); 
} 
else 
{ 
m_text.append(m_a); 
} 
} 
}
Thread Safety 
• Code is marked thread-safe if it’s ok to use 
it from multiple threads, on the same 
instance. 
• Thread-safe code manages data access
Other Considerations 
• When locking threads, you lose 
concurrency 
• Previous example was better written by: 
• Separating the problem to sections 
• Solving each section in a thread
Locking Options 
• QMutex 
• QSemaphore 
• QReadWriteLock 
• QWaitCondition
QMutex 
• Only one thread can “hold” a mutex 
• Others wait till done 
• Like the java’s synchronized keyword
QMutex Demo 
• Consider the two 
methods on the right 
• If called from 
multiple threads, 
they’ll break 
int number = 6; 
void method1() 
{ 
number *= 5; 
number /= 4; 
} 
void method2() 
{ 
number *= 3; 
number /= 2; 
}
QMutex Demo 
• But the mutex 
changes everything 
• Now method2 has to 
wait for method1 to 
finish 
QMutex mutex; 
int number = 6; 
void method1() 
{ 
mutex.lock(); 
number *= 5; 
number /= 4; 
mutex.unlock(); 
} 
void method2() 
{ 
mutex.lock(); 
number *= 3; 
number /= 2; 
mutex.unlock(); 
}
Deadlocks 
• Forgetting to unlock 
a mutex creates 
deadlocks 
• Unlocking in a wrong 
order creates 
deadlocks
QMutexLocker 
With QMutexLocker, you’ll never forget to 
unlock your mutex 
virtual void run() 
{ 
QMutexLocker l(&mutex); 
num = 6; 
m1(); 
m2(); 
qDebug() << QThread::currentThreadId() << ") n = " << num; 
}
Q & A
Lab 
• Modify Counter code so it is thread safe
QReadWriteLock 
• Multiple reads, single write 
• Prevents starvation
Demo 
• Write a QRunnable class to run the 
following code 
• Did you segfault ? Good, now fix it 
virtual void run() 
{ 
if ( m_writer ) 
{ 
m_list << QString::number(qrand()); 
} 
else 
{ 
qDebug() << m_list; 
} 
}
QReadWriteLock vs. QMutex 
• Use QReadWriteLock when you have many 
readers and few writers 
• For other cases, mutex is sufficient
QSemaphore 
• Producer-Consumer problem 
• One producer, multiple consumers
QSemaphore 
• A general counting semaphore 
• Methods: 
• acquire(n) 
• release(n)
Demo Code 
QSemaphore sem(5); // sem.available() == 5 
sem.acquire(3); // sem.available() == 2 
sem.acquire(2); // sem.available() == 0 
sem.release(5); // sem.available() == 5 
sem.release(5); // sem.available() == 10 
sem.tryAcquire(1); // sem.available() == 9, returns true 
sem.tryAcquire(250); // sem.available() == 9, returns false
Locking Alternatives 
• Locking mechanisms are used to sync with 
worker threads 
• Some alternatives: 
• Using QtConcurrent algorithms
Q & A
Qt Style Worker Thread 
Main Event 
Loop 
Secondary 
Event Loop 
Signals and Slots
The Code 
• Create a worker 
thread as a normal 
QObject 
• Move it to another 
thread 
• Start the thread’s 
event loop 
MyWorker w; 
QThread t; 
w.moveToThread(&t); 
t.start();
Why Is It Awesome 
• Write code with normal signals and slots 
• Make it multi-threaded when needed 
• Almost no change
Under The Hood 
• QObject::connect uses a message queue 
to call slots in other threads
Lab 
• Write a GUI app that displays an image 
• Use QFileDialog to choose image file 
• Read image file from a worker thread
Concurrent Algorithms
Concurrent Algorithms 
• Algorithms on collections can make use of 
concurrent primitives 
• Qt provides: 
• map 
• filter 
• reduce
Let’s Start With A Demo 
int main(int argc, char *argv[]) 
{ 
QCoreApplication a(argc, argv); 
QList<long> seq; 
QTime t1,t2; 
for (long i=2; i < 100000; i++ ) seq << i; 
t1.start(); 
QtConcurrent::blockingFiltered(seq, isPrime); 
qDebug("Time elapsed (Multi): %d ms", t1.elapsed()); 
t2.start(); 
foreach ( long n, seq ) isPrime(n); 
qDebug("Time elapsed (Single): %d ms", t2.elapsed()); 
return 0; 
}
Results 
Time elapsed (Multi): 1433 ms 
Time elapsed (Single): 3408 ms
The Good Parts 
• Easily implement algorithms 
on collections 
• Avoid common mistakes 
• No need to synchronize threads
Other Primitives 
• map applies a function to each item in 
the collection, returning a list of the results 
• mappedReduced does map and reduces 
the result
Other Primitives 
• filter applies a function on each item in 
the collection, returning a list of the 
“true” ones 
• filteredReduced does the same, and also 
reduces to a single result
Progress Indication 
• Algorithms return QFuture object 
• Use QFutureWatcher to add signals and 
slots
Demo Code 
QFutureWatcher<long> w; 
ProgressReporter p; 
w.setFuture(QtConcurrent::filtered(seq, isPrime)); 
QObject::connect(&w, SIGNAL(progressRangeChanged(int,int)), 
&p, SLOT(progressRangeChanged(int,int))); 
QObject::connect(&w, SIGNAL(progressValueChanged(int)), 
&p, SLOT(progressValueChanged(int)));
Progress Notes 
• QFutureWatcher is templated to the type 
of the list 
• Progressive filling is possible with: 
• resultReadyAt(int) 
• resultsReadyAt(int,int) 
• Best gain: no latency
Q & A
Concurrency Takeaways 
• Use worker threads for IO 
• Use QtConcurrent for algorithms 
• Latency is the enemy
Lab 
• Move our prime number detection code 
to a GUI app 
• User selects range, and the application 
prints all prime numbers in range 
• Try with and without QtConcurrent
Online Resources 
• http://qt-project.org/doc/qt-5.0/qtcore/ 
thread-basics.html 
• http://www.greenteapress.com/ 
semaphores/ 
• http://qt-project.org/videos/watch/ 
threaded_programming_with_qt
Thanks For Listening 
• Ynon Perek 
• ynon@ynonperek.com 
• http://ynonperek.com

More Related Content

PDF
QThreads: Are You Using Them Wrong?
ICS
 
PDF
Qt Internationalization
ICS
 
PDF
02 - Basics of Qt
Andreas Jakl
 
PDF
In-Depth Model/View with QML
ICS
 
PPTX
Qt Framework Events Signals Threads
Neera Mital
 
PPTX
Qt for beginners part 1 overview and key concepts
ICS
 
PDF
Qt Application Programming with C++ - Part 1
Emertxe Information Technologies Pvt Ltd
 
PDF
Best Practices in Qt Quick/QML - Part 1 of 4
ICS
 
QThreads: Are You Using Them Wrong?
ICS
 
Qt Internationalization
ICS
 
02 - Basics of Qt
Andreas Jakl
 
In-Depth Model/View with QML
ICS
 
Qt Framework Events Signals Threads
Neera Mital
 
Qt for beginners part 1 overview and key concepts
ICS
 
Qt Application Programming with C++ - Part 1
Emertxe Information Technologies Pvt Ltd
 
Best Practices in Qt Quick/QML - Part 1 of 4
ICS
 

What's hot (20)

PDF
Introduction to QML
Alan Uthoff
 
ODP
Qt 5 - C++ and Widgets
Juha Peltomäki
 
PDF
Basics of Model/View Qt programming
ICS
 
PDF
Best Practices in Qt Quick/QML - Part 3
ICS
 
PDF
Qt Design Patterns
Ynon Perek
 
PPTX
Best Practices in Qt Quick/QML - Part I
ICS
 
PPTX
Qt Qml
Steven Song
 
PDF
Best Practices in Qt Quick/QML - Part II
ICS
 
PDF
Best Practices in Qt Quick/QML - Part IV
ICS
 
PPTX
UI Programming with Qt-Quick and QML
Emertxe Information Technologies Pvt Ltd
 
PDF
Best Practices in Qt Quick/QML - Part 4
ICS
 
ODP
Qt Workshop
Johan Thelin
 
PDF
QVariant, QObject — Qt's not just for GUI development
ICS
 
PDF
Best Practices in Qt Quick/QML - Part III
ICS
 
PDF
Introduction to Qt Creator
Qt
 
PDF
Qt programming-using-cpp
Emertxe Information Technologies Pvt Ltd
 
PPTX
Introduction to Qt
Puja Pramudya
 
PPTX
Kotlin presentation
MobileAcademy
 
PPT
Qt Technical Presentation
Daniel Rocha
 
PDF
Qt for beginners
Sergio Shevchenko
 
Introduction to QML
Alan Uthoff
 
Qt 5 - C++ and Widgets
Juha Peltomäki
 
Basics of Model/View Qt programming
ICS
 
Best Practices in Qt Quick/QML - Part 3
ICS
 
Qt Design Patterns
Ynon Perek
 
Best Practices in Qt Quick/QML - Part I
ICS
 
Qt Qml
Steven Song
 
Best Practices in Qt Quick/QML - Part II
ICS
 
Best Practices in Qt Quick/QML - Part IV
ICS
 
UI Programming with Qt-Quick and QML
Emertxe Information Technologies Pvt Ltd
 
Best Practices in Qt Quick/QML - Part 4
ICS
 
Qt Workshop
Johan Thelin
 
QVariant, QObject — Qt's not just for GUI development
ICS
 
Best Practices in Qt Quick/QML - Part III
ICS
 
Introduction to Qt Creator
Qt
 
Introduction to Qt
Puja Pramudya
 
Kotlin presentation
MobileAcademy
 
Qt Technical Presentation
Daniel Rocha
 
Qt for beginners
Sergio Shevchenko
 
Ad

Viewers also liked (8)

PDF
State of the Art OpenGL and Qt
ICS
 
PDF
[Webinar] 10 Keys to Ensuring Success for Your Next Qt Project
ICS
 
PPTX
Reminder Application by Qt and C++
Sumaia Alavi
 
PPT
Using QString effectively
Roman Okolovich
 
PDF
qmake入門
hermit4 Ishida
 
PDF
Convert Your Legacy OpenGL Code to Modern OpenGL with Qt
ICS
 
PDF
Regexp
Ynon Perek
 
PDF
Qt for Beginners Part 3 - QML and Qt Quick
ICS
 
State of the Art OpenGL and Qt
ICS
 
[Webinar] 10 Keys to Ensuring Success for Your Next Qt Project
ICS
 
Reminder Application by Qt and C++
Sumaia Alavi
 
Using QString effectively
Roman Okolovich
 
qmake入門
hermit4 Ishida
 
Convert Your Legacy OpenGL Code to Modern OpenGL with Qt
ICS
 
Regexp
Ynon Perek
 
Qt for Beginners Part 3 - QML and Qt Quick
ICS
 
Ad

Similar to Qt multi threads (20)

PDF
Qt Application Programming with C++ - Part 2
Emertxe Information Technologies Pvt Ltd
 
PDF
C++ CoreHard Autumn 2018. Concurrency and Parallelism in C++17 and C++20/23 -...
corehard_by
 
PDF
Lockless Producer Consumer Threads: Asynchronous Communications Made Easy
ICS
 
ODP
Multithreading 101
Tim Penhey
 
PDF
Giorgio zoppi cpp11concurrency
Giorgio Zoppi
 
PDF
40d5984d819aaa72e55aa10376b73bde_MIT6_087IAP10_lec12.pdf
SagarYadav642223
 
PPT
Shared Memory Programming with Pthreads (1).ppt
MALARMANNANA1
 
PPTX
Shared Memory Programming with Pthreads and OpenMP
Dilum Bandara
 
PPTX
Multithreading and concurrency in android
Rakesh Jha
 
PDF
Степан Кольцов — Message passing: многопоточное программирование без мьютексов
Yandex
 
PDF
System Programming - Threading
HelpWithAssignment.com
 
PDF
Introduction to multicore .ppt
Rajagopal Nagarajan
 
PPTX
Synchronizing Concurrent Operations in C++.pptx
emsResulzade1
 
PDF
Other Approaches (Concurrency)
Sri Prasanna
 
PDF
AOS Lab 4: If you liked it, then you should have put a “lock” on it
Zubair Nabi
 
PDF
Topic 4: Concurrency
Zubair Nabi
 
PDF
Concurrency vs parallelism
Yiwei Gong
 
PPTX
CS345 09 - Ch04 Threads operating system1.pptx
RichaAgnihotri13
 
PPT
Parallel Programming: Beyond the Critical Section
Tony Albrecht
 
Qt Application Programming with C++ - Part 2
Emertxe Information Technologies Pvt Ltd
 
C++ CoreHard Autumn 2018. Concurrency and Parallelism in C++17 and C++20/23 -...
corehard_by
 
Lockless Producer Consumer Threads: Asynchronous Communications Made Easy
ICS
 
Multithreading 101
Tim Penhey
 
Giorgio zoppi cpp11concurrency
Giorgio Zoppi
 
40d5984d819aaa72e55aa10376b73bde_MIT6_087IAP10_lec12.pdf
SagarYadav642223
 
Shared Memory Programming with Pthreads (1).ppt
MALARMANNANA1
 
Shared Memory Programming with Pthreads and OpenMP
Dilum Bandara
 
Multithreading and concurrency in android
Rakesh Jha
 
Степан Кольцов — Message passing: многопоточное программирование без мьютексов
Yandex
 
System Programming - Threading
HelpWithAssignment.com
 
Introduction to multicore .ppt
Rajagopal Nagarajan
 
Synchronizing Concurrent Operations in C++.pptx
emsResulzade1
 
Other Approaches (Concurrency)
Sri Prasanna
 
AOS Lab 4: If you liked it, then you should have put a “lock” on it
Zubair Nabi
 
Topic 4: Concurrency
Zubair Nabi
 
Concurrency vs parallelism
Yiwei Gong
 
CS345 09 - Ch04 Threads operating system1.pptx
RichaAgnihotri13
 
Parallel Programming: Beyond the Critical Section
Tony Albrecht
 

More from Ynon Perek (20)

PDF
Html5 intro
Ynon Perek
 
PDF
09 performance
Ynon Perek
 
PDF
Mobile Web Intro
Ynon Perek
 
PDF
Vimperl
Ynon Perek
 
PDF
Syllabus
Ynon Perek
 
PDF
Mobile Devices
Ynon Perek
 
PDF
Network
Ynon Perek
 
PDF
Architecture app
Ynon Perek
 
PDF
Cryptography
Ynon Perek
 
PDF
Unit Testing JavaScript Applications
Ynon Perek
 
PDF
How to write easy-to-test JavaScript
Ynon Perek
 
PDF
Introduction to Selenium and Ruby
Ynon Perek
 
PDF
Introduction To Web Application Testing
Ynon Perek
 
PDF
Accessibility
Ynon Perek
 
PDF
Angularjs
Ynon Perek
 
PDF
Js memory
Ynon Perek
 
PDF
Web Application Security
Ynon Perek
 
PDF
JavaScript DOM Manipulations
Ynon Perek
 
PDF
Mongodb Intro
Ynon Perek
 
PDF
Node JS
Ynon Perek
 
Html5 intro
Ynon Perek
 
09 performance
Ynon Perek
 
Mobile Web Intro
Ynon Perek
 
Vimperl
Ynon Perek
 
Syllabus
Ynon Perek
 
Mobile Devices
Ynon Perek
 
Network
Ynon Perek
 
Architecture app
Ynon Perek
 
Cryptography
Ynon Perek
 
Unit Testing JavaScript Applications
Ynon Perek
 
How to write easy-to-test JavaScript
Ynon Perek
 
Introduction to Selenium and Ruby
Ynon Perek
 
Introduction To Web Application Testing
Ynon Perek
 
Accessibility
Ynon Perek
 
Angularjs
Ynon Perek
 
Js memory
Ynon Perek
 
Web Application Security
Ynon Perek
 
JavaScript DOM Manipulations
Ynon Perek
 
Mongodb Intro
Ynon Perek
 
Node JS
Ynon Perek
 

Recently uploaded (20)

PPTX
New ThousandEyes Product Innovations: Cisco Live June 2025
ThousandEyes
 
PDF
Make GenAI investments go further with the Dell AI Factory - Infographic
Principled Technologies
 
DOCX
Top AI API Alternatives to OpenAI: A Side-by-Side Breakdown
vilush
 
PPTX
Smart Infrastructure and Automation through IoT Sensors
Rejig Digital
 
PDF
Enable Enterprise-Ready Security on IBM i Systems.pdf
Precisely
 
PDF
Chapter 2 Digital Image Fundamentals.pdf
Getnet Tigabie Askale -(GM)
 
PDF
CIFDAQ's Token Spotlight: SKY - A Forgotten Giant's Comeback?
CIFDAQ
 
PDF
Unlocking the Future- AI Agents Meet Oracle Database 23ai - AIOUG Yatra 2025.pdf
Sandesh Rao
 
PDF
CIFDAQ's Teaching Thursday: Moving Averages Made Simple
CIFDAQ
 
PDF
NewMind AI Weekly Chronicles - July'25 - Week IV
NewMind AI
 
PDF
Why Your AI & Cybersecurity Hiring Still Misses the Mark in 2025
Virtual Employee Pvt. Ltd.
 
PDF
Test Bank, Solutions for Java How to Program, An Objects-Natural Approach, 12...
famaw19526
 
PDF
Security features in Dell, HP, and Lenovo PC systems: A research-based compar...
Principled Technologies
 
PDF
NewMind AI Monthly Chronicles - July 2025
NewMind AI
 
PDF
A Day in the Life of Location Data - Turning Where into How.pdf
Precisely
 
PPTX
Comunidade Salesforce São Paulo - Desmistificando o Omnistudio (Vlocity)
Francisco Vieira Júnior
 
PDF
Oracle AI Vector Search- Getting Started and what's new in 2025- AIOUG Yatra ...
Sandesh Rao
 
PDF
Doc9.....................................
SofiaCollazos
 
PDF
Cloud-Migration-Best-Practices-A-Practical-Guide-to-AWS-Azure-and-Google-Clou...
Artjoker Software Development Company
 
PDF
Google’s NotebookLM Unveils Video Overviews
SOFTTECHHUB
 
New ThousandEyes Product Innovations: Cisco Live June 2025
ThousandEyes
 
Make GenAI investments go further with the Dell AI Factory - Infographic
Principled Technologies
 
Top AI API Alternatives to OpenAI: A Side-by-Side Breakdown
vilush
 
Smart Infrastructure and Automation through IoT Sensors
Rejig Digital
 
Enable Enterprise-Ready Security on IBM i Systems.pdf
Precisely
 
Chapter 2 Digital Image Fundamentals.pdf
Getnet Tigabie Askale -(GM)
 
CIFDAQ's Token Spotlight: SKY - A Forgotten Giant's Comeback?
CIFDAQ
 
Unlocking the Future- AI Agents Meet Oracle Database 23ai - AIOUG Yatra 2025.pdf
Sandesh Rao
 
CIFDAQ's Teaching Thursday: Moving Averages Made Simple
CIFDAQ
 
NewMind AI Weekly Chronicles - July'25 - Week IV
NewMind AI
 
Why Your AI & Cybersecurity Hiring Still Misses the Mark in 2025
Virtual Employee Pvt. Ltd.
 
Test Bank, Solutions for Java How to Program, An Objects-Natural Approach, 12...
famaw19526
 
Security features in Dell, HP, and Lenovo PC systems: A research-based compar...
Principled Technologies
 
NewMind AI Monthly Chronicles - July 2025
NewMind AI
 
A Day in the Life of Location Data - Turning Where into How.pdf
Precisely
 
Comunidade Salesforce São Paulo - Desmistificando o Omnistudio (Vlocity)
Francisco Vieira Júnior
 
Oracle AI Vector Search- Getting Started and what's new in 2025- AIOUG Yatra ...
Sandesh Rao
 
Doc9.....................................
SofiaCollazos
 
Cloud-Migration-Best-Practices-A-Practical-Guide-to-AWS-Azure-and-Google-Clou...
Artjoker Software Development Company
 
Google’s NotebookLM Unveils Video Overviews
SOFTTECHHUB
 

Qt multi threads

  • 2. Agenda • Doing things simultaneously • Using the event loop • Using threads • Using QtConcurrent algorithms
  • 3. The Event Loop MainLoop event 1 Handler Handler Handler
  • 4. You’re Already Doing It • Network code runs in parallel • Timers
  • 5. Unfortunately … • DB queries block • Disk operations block • CPU operations block
  • 7. What We Need • Run something “in the background” • A single task • A worker thread • A full algorithm • Another application
  • 8. Single Task QThread QThreadPool QRunnable Thread Synchronization
  • 9. Threads Theory • Define tasks by extending QRunnable • Use QThreadsPool to run them
  • 10. Demo Runnable class MyTask : public QRunnable { virtual void run() { for ( int i=0; i < 10; i++ ) { qDebug() << "[" << QThread::currentThreadId() << "]" << " " << i; } } };
  • 11. Using The Thread Pool QCoreApplication a(argc, argv); MyTask *t1 = new MyTask; QThreadPool p; p.start(t1); p.waitForDone();
  • 12. Thread Pool Notes • start() takes ownership of the runnable. It will be deleted when done • Number of threads matches number of CPU cores • waitForDone() stops the event loop. Be careful with that one
  • 13. Yielding • If you feel your thread has worked hard enough, rest with: QThread::yieldCurrentThread();
  • 14. Sharing • Cool in real life • Uncool for threads
  • 15. Sharing Problems • Shared resources can be manipulated from other threads • Even when you’re in the middle
  • 16. Sharing Problems Can you use the code below from multiple threads ? class Counter { public: Counter() { n = 0; } void increment() { ++n; } void decrement() { --n; } int value() const { return n; } private: int n; }; Why ?
  • 17. Sharing Problems • Most Qt and C++ code is re-entrant • It means you can’t access same instance from different threads at the same time
  • 18. Quiz • Assume m_text is a QStringList • Can you use the code from multiple threads ? Why ? virtual void run() { m_text.append(m_a); for ( int i=0; i < 100; i++ ) { if ( m_text.last() == m_a ) { m_text.append(m_b); } else { m_text.append(m_a); } } }
  • 19. Thread Safety • Code is marked thread-safe if it’s ok to use it from multiple threads, on the same instance. • Thread-safe code manages data access
  • 20. Other Considerations • When locking threads, you lose concurrency • Previous example was better written by: • Separating the problem to sections • Solving each section in a thread
  • 21. Locking Options • QMutex • QSemaphore • QReadWriteLock • QWaitCondition
  • 22. QMutex • Only one thread can “hold” a mutex • Others wait till done • Like the java’s synchronized keyword
  • 23. QMutex Demo • Consider the two methods on the right • If called from multiple threads, they’ll break int number = 6; void method1() { number *= 5; number /= 4; } void method2() { number *= 3; number /= 2; }
  • 24. QMutex Demo • But the mutex changes everything • Now method2 has to wait for method1 to finish QMutex mutex; int number = 6; void method1() { mutex.lock(); number *= 5; number /= 4; mutex.unlock(); } void method2() { mutex.lock(); number *= 3; number /= 2; mutex.unlock(); }
  • 25. Deadlocks • Forgetting to unlock a mutex creates deadlocks • Unlocking in a wrong order creates deadlocks
  • 26. QMutexLocker With QMutexLocker, you’ll never forget to unlock your mutex virtual void run() { QMutexLocker l(&mutex); num = 6; m1(); m2(); qDebug() << QThread::currentThreadId() << ") n = " << num; }
  • 27. Q & A
  • 28. Lab • Modify Counter code so it is thread safe
  • 29. QReadWriteLock • Multiple reads, single write • Prevents starvation
  • 30. Demo • Write a QRunnable class to run the following code • Did you segfault ? Good, now fix it virtual void run() { if ( m_writer ) { m_list << QString::number(qrand()); } else { qDebug() << m_list; } }
  • 31. QReadWriteLock vs. QMutex • Use QReadWriteLock when you have many readers and few writers • For other cases, mutex is sufficient
  • 32. QSemaphore • Producer-Consumer problem • One producer, multiple consumers
  • 33. QSemaphore • A general counting semaphore • Methods: • acquire(n) • release(n)
  • 34. Demo Code QSemaphore sem(5); // sem.available() == 5 sem.acquire(3); // sem.available() == 2 sem.acquire(2); // sem.available() == 0 sem.release(5); // sem.available() == 5 sem.release(5); // sem.available() == 10 sem.tryAcquire(1); // sem.available() == 9, returns true sem.tryAcquire(250); // sem.available() == 9, returns false
  • 35. Locking Alternatives • Locking mechanisms are used to sync with worker threads • Some alternatives: • Using QtConcurrent algorithms
  • 36. Q & A
  • 37. Qt Style Worker Thread Main Event Loop Secondary Event Loop Signals and Slots
  • 38. The Code • Create a worker thread as a normal QObject • Move it to another thread • Start the thread’s event loop MyWorker w; QThread t; w.moveToThread(&t); t.start();
  • 39. Why Is It Awesome • Write code with normal signals and slots • Make it multi-threaded when needed • Almost no change
  • 40. Under The Hood • QObject::connect uses a message queue to call slots in other threads
  • 41. Lab • Write a GUI app that displays an image • Use QFileDialog to choose image file • Read image file from a worker thread
  • 43. Concurrent Algorithms • Algorithms on collections can make use of concurrent primitives • Qt provides: • map • filter • reduce
  • 44. Let’s Start With A Demo int main(int argc, char *argv[]) { QCoreApplication a(argc, argv); QList<long> seq; QTime t1,t2; for (long i=2; i < 100000; i++ ) seq << i; t1.start(); QtConcurrent::blockingFiltered(seq, isPrime); qDebug("Time elapsed (Multi): %d ms", t1.elapsed()); t2.start(); foreach ( long n, seq ) isPrime(n); qDebug("Time elapsed (Single): %d ms", t2.elapsed()); return 0; }
  • 45. Results Time elapsed (Multi): 1433 ms Time elapsed (Single): 3408 ms
  • 46. The Good Parts • Easily implement algorithms on collections • Avoid common mistakes • No need to synchronize threads
  • 47. Other Primitives • map applies a function to each item in the collection, returning a list of the results • mappedReduced does map and reduces the result
  • 48. Other Primitives • filter applies a function on each item in the collection, returning a list of the “true” ones • filteredReduced does the same, and also reduces to a single result
  • 49. Progress Indication • Algorithms return QFuture object • Use QFutureWatcher to add signals and slots
  • 50. Demo Code QFutureWatcher<long> w; ProgressReporter p; w.setFuture(QtConcurrent::filtered(seq, isPrime)); QObject::connect(&w, SIGNAL(progressRangeChanged(int,int)), &p, SLOT(progressRangeChanged(int,int))); QObject::connect(&w, SIGNAL(progressValueChanged(int)), &p, SLOT(progressValueChanged(int)));
  • 51. Progress Notes • QFutureWatcher is templated to the type of the list • Progressive filling is possible with: • resultReadyAt(int) • resultsReadyAt(int,int) • Best gain: no latency
  • 52. Q & A
  • 53. Concurrency Takeaways • Use worker threads for IO • Use QtConcurrent for algorithms • Latency is the enemy
  • 54. Lab • Move our prime number detection code to a GUI app • User selects range, and the application prints all prime numbers in range • Try with and without QtConcurrent
  • 55. Online Resources • http://qt-project.org/doc/qt-5.0/qtcore/ thread-basics.html • http://www.greenteapress.com/ semaphores/ • http://qt-project.org/videos/watch/ threaded_programming_with_qt
  • 56. Thanks For Listening • Ynon Perek • [email protected] • http://ynonperek.com