SlideShare a Scribd company logo
1 of 35
Download to read offline
Item 35:
Prefer task-based programming to
thread-based.
Item 36:
Specify std::launch::async if
asynchronicity is essential.
BE RATIONAL, NOT SOUR.
Tommy Kuo [:KuoE0]
kuoe0@mozilla.com
Effective Modern C++
Item 35:
Prefer task-based programming
to thread-based.
Concurrency in C++11
int doAsyncWork();
// thread-based programming
std::thread t(doAsyncWork);
// task-based programming
auto fut = std::async(doAsyncWork);
std::future<int>
Return Valueuse get() to get the return value
std::async
function
std::future
object
return
int fib(int x) {
return x <= 2 ? x - 1 : fib(x - 1) + fib(x -
2);
}
int main() {
auto fut = std::async(fib, 40);
auto ret = fut.get();
std::cout << ret << std::endl;
return 0;
}
std::future::get
function
call
Handle Erroruse get() to throw exceptions
std::async
function
std::future
object
return
int fib(int x) {
if (x < 1) throw logic_error("Don't you know
Fibonacci?");
return x <= 2 ? x - 1 : fib(x - 1) + fib(x - 2);
}
int main() {
auto fut = async(fib, 0);
try {
cout << fut.get() << endl;
} catch(exception& e) {
cout << e.what() << endl;
}
return 0;
}
std::future::get
function
call
throw exception
Handle Error with std::thread
int fib(int x) {
if (x < 1) throw logic_error("Don't you know Fibonacci?");
return x <= 2 ? x - 1 : fib(x - 1) + fib(x - 2);
}
int main() {
try {
auto t = thread(fib, 0);
} catch(exception& e) {
cout << e.what() << endl;
}
return 0;
}
throw exception
Program terminated! CC 2.0
Nightmare with Thread Management
(thread exhaustion)
system provides
6 threads.
int main() {
std::vector<std::thread> thread_pool(1000);
return 0;
}
throw std::system_error exception
more than system can provide
Nightmare with Thread Management
(oversubscription)
CPU provides
2 threads
system has
100 threads
ready to run
× 100
oversubscription
Nightmare with Thread Management
(oversubscription)
CPU provides
2 threads
system has
100 threads
ready to run
× 100
Context switches increase the
overall thread management
overhead of the system.
oversubscription
– Effective Modern C++, Scott Meyer
“Your life will be easier if you dump these problems
on somebody else, and using std::async.”
std::async takes responsibility for thread management.
#1, running task 1
#2, running task 2
#3, empty
task 3
task 4
task 5
task 6
task 7
task queue
Discuss in item 36 later :)
BUT
When to Use std::thread
- Need access to the API of the underlying threading
implementation.

Using std::thread::native_handle to get the lower-level platform-
specific thread (pthreads or Windows’ Threads).
- Need to and are able to optimize thread usage.

- Need to implement threading technology beyond the C++
concurrency API.
Things to Remember
- The std::thread API offers no direct way to get return values from
asynchronously run functions, and if those functions throw, the program is
terminated.
- Thread-based programming calls for manual management of thread
exhaustion, oversubscription, load balancing, and adaptation to new
platforms.
- Task-based programming via std::async with the default launch policy
handles most of these issues for you.
Item 36:
Specify std::launch::async if
asynchronicity is essential.
Launch Policy of std::async
- std::launch::async
Task must be run asynchronously.
- std::launch::deferred
Task may run only when get or wait is called on the future
returned by std::async.
You have to present
on 2016/01/06.
2015/10/01 2015/10/01
Junior
Done. 😎
2015/10/02 2016/01/05
I hope I can finish it
before Wednesday. 😭
You have to present
on 2016/01/06.
Junior
Tommy (with async-driven) Tommy (with deferred-driven)
behavior of async policy behavior of deferred policy
OK! 😎
Tommy (with async-driven)
OK! 😎
Tommy (with async-driven)
Are you ready?
Junior
Are you ready?
Junior
Default Launch Policy
auto fut = std::async(task);
// create with default launch policy
auto fut = std::async(std::launch::async |
std::launch::deferred, task);
// as same as the default launch policy
The default policy thus permits tasks to be run either
asynchronously or synchronously.
- Not possible to predict whether tasks will run concurrently.
- Not possible to predict whether tasks run on a thread
different from the thread invoking get or wait.
- May not be possible to predict whether tasks run at all.
std::async(task)
async policy
deferred policy
looks good!
thread_local variables
timeout-based wait
affect
With deferred policy,
thread_local variables will act as
normal global variables.
thread_local variables with async policy
thread_local int x = 0;
int func(bool update, int val){
return update ? x = val : x;
}
int main(){
x = 9;
std::future<int> task[4];
for (int i = 0; i < 3; ++i) task[i] =
std::async(std::launch::async, func, true, i + 1);
task[3] = std::async(std::launch::async, func, false, 0);
for (auto& t: task) std::cout << t.get();
std::cout << x << std::endl;
return 0;
}
thread_local variables with async policy
thread_local int x = 0;
int func(bool update, int val){
return update ? x = val : x;
}
int main(){
x = 9;
std::future<int> task[4];
for (int i = 0; i < 3; ++i) task[i] =
std::async(std::launch::async, func, true, i + 1);
task[3] = std::async(std::launch::async, func, false, 0);
for (auto& t: task) std::cout << t.get();
std::cout << x << std::endl;
return 0;
}
output
——————————————————————
12309
thread_local variables with deferred policy
thread_local int x = 0;
int func(bool update, int val){
return update ? x = val : x;
}
int main(){
x = 9;
std::future<int> task[4];
for (int i = 0; i < 3; ++i) task[i] =
std::async(std::launch::deferred, func, true, i + 1);
task[3] = std::async(std::launch::deferred, func, false, 0);
for (auto& t: task) std::cout << t.get();
std::cout << x << std::endl;
return 0;
}
thread_local variables with deferred policy
thread_local int x = 0;
int func(bool update, int val){
return update ? x = val : x;
}
int main(){
x = 9;
std::future<int> task[4];
for (int i = 0; i < 3; ++i) task[i] =
std::async(std::launch::deferred, func, true, i + 1);
task[3] = std::async(std::launch::deferred, func, false, 0);
for (auto& t: task) std::cout << t.get();
std::cout << x << std::endl;
return 0;
}
output
——————————————————————
12333
With deferred policy, wait_for
and wait_until will return
std::future_status::deferred.
Infinite-loop problem with timeout-based wait
int main() {
auto fut = std::async(std::launch::deferred,
task); // deferred policy
while (fut.wait_for(100ms) !=
std::future_status::ready) {
std::cout << “waiting…” << std::endl;
}
std::cout << fut.get() << std::endl;
return 0;
}
return std::future_status::deferred always
Resolve infinite-loop problem
int main() {
auto fut = std::async(task); // deferred policy
if (fut.wait_for(0ms) ==
std::future_status::deferred) {
fut.wait(); // fut.get() also works.
} else {
while (fut.wait_for(100ms) !=
std::future_status::ready) {
std::cout << “waiting…” << std::endl;
}
}
std::cout << fut.get() << std::endl;
return 0;
}
check it and make it
run synchronously
BUT
When to Use Default Launch Policy
- The task need not run concurrently with the thread calling get or wait. 

- It doesn’t matter which thread’s thread_local variables are read or written. 

- Either there’s a guarantee that get or wait will be called on the future
returned by std::async.

- It’s acceptable that the task may never execute.

- Code using wait_for or wait_until takes the possibility of deferred status
into account.
Function to Use Async Policy (C++11)
template<typename F, typename... Ts>
inline
std::future<typename std::result_of<F(Ts…)>::type>
reallyAsync(F&& f, Ts&&... params)
{
return std::async(std::launch::async,
std::forward<F>(f),
std::forward<Ts>(params)…);
}
Function to Use Async Policy (C++14)
template<typename F, typename... Ts>
inline
auto
reallyAsync(F&& f, Ts&&... params)
{
return std::async(std::launch::async,
std::forward<F>(f),
std::forward<Ts>(params)…);
}
Things to Remember
- The default launch policy for std::async permits both
asynchronous and synchronous task execution.
- This flexibility leads to uncertainty when accessing thread_local
variables, implies that the task may never execute, and affects
program logic for timeout-based wait calls.
- Specify std::launch::async if asynchronous task execution is
essential.
Thanks.
CC-BY-SA

More Related Content

What's hot

Linux 4.x Tracing Tools: Using BPF Superpowers
Linux 4.x Tracing Tools: Using BPF SuperpowersLinux 4.x Tracing Tools: Using BPF Superpowers
Linux 4.x Tracing Tools: Using BPF Superpowers
Brendan Gregg
 
Uboot startup sequence
Uboot startup sequenceUboot startup sequence
Uboot startup sequence
Houcheng Lin
 
Mercurial簡介與教學
Mercurial簡介與教學Mercurial簡介與教學
Mercurial簡介與教學
芳本 林
 

What's hot (20)

Gor Nishanov, C++ Coroutines – a negative overhead abstraction
Gor Nishanov,  C++ Coroutines – a negative overhead abstractionGor Nishanov,  C++ Coroutines – a negative overhead abstraction
Gor Nishanov, C++ Coroutines – a negative overhead abstraction
 
Quickboot on i.MX6
Quickboot on i.MX6Quickboot on i.MX6
Quickboot on i.MX6
 
Debugging linux kernel tools and techniques
Debugging linux kernel tools and  techniquesDebugging linux kernel tools and  techniques
Debugging linux kernel tools and techniques
 
Measuring P99 Latency in Event-Driven Architectures with OpenTelemetry
Measuring P99 Latency in Event-Driven Architectures with OpenTelemetryMeasuring P99 Latency in Event-Driven Architectures with OpenTelemetry
Measuring P99 Latency in Event-Driven Architectures with OpenTelemetry
 
ROP 輕鬆談
ROP 輕鬆談ROP 輕鬆談
ROP 輕鬆談
 
Linux Internals - Part III
Linux Internals - Part IIILinux Internals - Part III
Linux Internals - Part III
 
Linux Kernel - Virtual File System
Linux Kernel - Virtual File SystemLinux Kernel - Virtual File System
Linux Kernel - Virtual File System
 
Static partitioning virtualization on RISC-V
Static partitioning virtualization on RISC-VStatic partitioning virtualization on RISC-V
Static partitioning virtualization on RISC-V
 
Introduction To Linux Kernel Modules
Introduction To Linux Kernel ModulesIntroduction To Linux Kernel Modules
Introduction To Linux Kernel Modules
 
Linux 4.x Tracing Tools: Using BPF Superpowers
Linux 4.x Tracing Tools: Using BPF SuperpowersLinux 4.x Tracing Tools: Using BPF Superpowers
Linux 4.x Tracing Tools: Using BPF Superpowers
 
Linux binary Exploitation - Basic knowledge
Linux binary Exploitation - Basic knowledgeLinux binary Exploitation - Basic knowledge
Linux binary Exploitation - Basic knowledge
 
PART-2 : Mastering RTOS FreeRTOS and STM32Fx with Debugging
PART-2 : Mastering RTOS FreeRTOS and STM32Fx with DebuggingPART-2 : Mastering RTOS FreeRTOS and STM32Fx with Debugging
PART-2 : Mastering RTOS FreeRTOS and STM32Fx with Debugging
 
Memory model
Memory modelMemory model
Memory model
 
Pwning in c++ (basic)
Pwning in c++ (basic)Pwning in c++ (basic)
Pwning in c++ (basic)
 
CMake - Introduction and best practices
CMake - Introduction and best practicesCMake - Introduction and best practices
CMake - Introduction and best practices
 
Uboot startup sequence
Uboot startup sequenceUboot startup sequence
Uboot startup sequence
 
Dead Lock Analysis of spin_lock() in Linux Kernel (english)
Dead Lock Analysis of spin_lock() in Linux Kernel (english)Dead Lock Analysis of spin_lock() in Linux Kernel (english)
Dead Lock Analysis of spin_lock() in Linux Kernel (english)
 
Linux Internals - Interview essentials 4.0
Linux Internals - Interview essentials 4.0Linux Internals - Interview essentials 4.0
Linux Internals - Interview essentials 4.0
 
Mercurial簡介與教學
Mercurial簡介與教學Mercurial簡介與教學
Mercurial簡介與教學
 
Linux Memory Management with CMA (Contiguous Memory Allocator)
Linux Memory Management with CMA (Contiguous Memory Allocator)Linux Memory Management with CMA (Contiguous Memory Allocator)
Linux Memory Management with CMA (Contiguous Memory Allocator)
 

Viewers also liked

20140531 serebryany lecture01_fantastic_cpp_bugs
20140531 serebryany lecture01_fantastic_cpp_bugs20140531 serebryany lecture01_fantastic_cpp_bugs
20140531 serebryany lecture01_fantastic_cpp_bugs
Computer Science Club
 

Viewers also liked (20)

Ownership System in Rust
Ownership System in RustOwnership System in Rust
Ownership System in Rust
 
在開始工作以前,我以為我會寫扣。
在開始工作以前,我以為我會寫扣。在開始工作以前,我以為我會寫扣。
在開始工作以前,我以為我會寫扣。
 
Pocket Authentication with OAuth on Firefox OS
Pocket Authentication with OAuth on Firefox OSPocket Authentication with OAuth on Firefox OS
Pocket Authentication with OAuth on Firefox OS
 
Use C++ to Manipulate mozSettings in Gecko
Use C++ to Manipulate mozSettings in GeckoUse C++ to Manipulate mozSettings in Gecko
Use C++ to Manipulate mozSettings in Gecko
 
What you need to know to start developing WebVR
What you need to know to start developing WebVRWhat you need to know to start developing WebVR
What you need to know to start developing WebVR
 
Nug2004 yhe
Nug2004 yheNug2004 yhe
Nug2004 yhe
 
20140531 serebryany lecture01_fantastic_cpp_bugs
20140531 serebryany lecture01_fantastic_cpp_bugs20140531 serebryany lecture01_fantastic_cpp_bugs
20140531 serebryany lecture01_fantastic_cpp_bugs
 
Threading Bobbin Tutorial
Threading Bobbin TutorialThreading Bobbin Tutorial
Threading Bobbin Tutorial
 
Mnk hsa ppt
Mnk hsa pptMnk hsa ppt
Mnk hsa ppt
 
Parallel Programming
Parallel ProgrammingParallel Programming
Parallel Programming
 
Async await in C++
Async await in C++Async await in C++
Async await in C++
 
Pixel-Lab / Games:EDU / Michel Kripalani / Games Industry Overview and Trends
Pixel-Lab / Games:EDU / Michel Kripalani / Games Industry Overview and TrendsPixel-Lab / Games:EDU / Michel Kripalani / Games Industry Overview and Trends
Pixel-Lab / Games:EDU / Michel Kripalani / Games Industry Overview and Trends
 
David Shastry Experience Design Portfolio
David Shastry Experience Design PortfolioDavid Shastry Experience Design Portfolio
David Shastry Experience Design Portfolio
 
AMC Minor Technical Issues
AMC Minor Technical IssuesAMC Minor Technical Issues
AMC Minor Technical Issues
 
Getting Started in VR with JS
Getting Started in VR with JSGetting Started in VR with JS
Getting Started in VR with JS
 
Introductions of Messaging bot 做聊天機器人
Introductions of Messaging bot 做聊天機器人Introductions of Messaging bot 做聊天機器人
Introductions of Messaging bot 做聊天機器人
 
C++11
C++11C++11
C++11
 
C++11
C++11C++11
C++11
 
Artificial Intelligence in Computer and Video Games
Artificial Intelligence in Computer and Video GamesArtificial Intelligence in Computer and Video Games
Artificial Intelligence in Computer and Video Games
 
Unit Testing Express and Koa Middleware in ES2015
Unit Testing Express and Koa Middleware in ES2015Unit Testing Express and Koa Middleware in ES2015
Unit Testing Express and Koa Middleware in ES2015
 

Similar to Effective Modern C++ - Item 35 & 36

Similar to Effective Modern C++ - Item 35 & 36 (20)

Giorgio zoppi cpp11concurrency
Giorgio zoppi cpp11concurrencyGiorgio zoppi cpp11concurrency
Giorgio zoppi cpp11concurrency
 
lecture56.ppt
lecture56.pptlecture56.ppt
lecture56.ppt
 
Chapter 4
Chapter 4Chapter 4
Chapter 4
 
C++ CoreHard Autumn 2018. Concurrency and Parallelism in C++17 and C++20/23 -...
C++ CoreHard Autumn 2018. Concurrency and Parallelism in C++17 and C++20/23 -...C++ CoreHard Autumn 2018. Concurrency and Parallelism in C++17 and C++20/23 -...
C++ CoreHard Autumn 2018. Concurrency and Parallelism in C++17 and C++20/23 -...
 
functions
functionsfunctions
functions
 
A deep dive into PEP-3156 and the new asyncio module
A deep dive into PEP-3156 and the new asyncio moduleA deep dive into PEP-3156 and the new asyncio module
A deep dive into PEP-3156 and the new asyncio module
 
Cluj.py Meetup: Extending Python in C
Cluj.py Meetup: Extending Python in CCluj.py Meetup: Extending Python in C
Cluj.py Meetup: Extending Python in C
 
Refactoring for testability c++
Refactoring for testability c++Refactoring for testability c++
Refactoring for testability c++
 
PythonBrasil[8] - CPython for dummies
PythonBrasil[8] - CPython for dummiesPythonBrasil[8] - CPython for dummies
PythonBrasil[8] - CPython for dummies
 
Function
FunctionFunction
Function
 
Advanced Python, Part 2
Advanced Python, Part 2Advanced Python, Part 2
Advanced Python, Part 2
 
2 BytesC++ course_2014_c3_ function basics&parameters and overloading
2 BytesC++ course_2014_c3_ function basics&parameters and overloading2 BytesC++ course_2014_c3_ function basics&parameters and overloading
2 BytesC++ course_2014_c3_ function basics&parameters and overloading
 
Profiling in Python
Profiling in PythonProfiling in Python
Profiling in Python
 
Async fun
Async funAsync fun
Async fun
 
Function
FunctionFunction
Function
 
Object oriented programming system with C++
Object oriented programming system with C++Object oriented programming system with C++
Object oriented programming system with C++
 
用 Go 語言打造多台機器 Scale 架構
用 Go 語言打造多台機器 Scale 架構用 Go 語言打造多台機器 Scale 架構
用 Go 語言打造多台機器 Scale 架構
 
Lecture#6 functions in c++
Lecture#6 functions in c++Lecture#6 functions in c++
Lecture#6 functions in c++
 
Options and trade offs for parallelism and concurrency in Modern C++
Options and trade offs for parallelism and concurrency in Modern C++Options and trade offs for parallelism and concurrency in Modern C++
Options and trade offs for parallelism and concurrency in Modern C++
 
Simple, fast, and scalable torch7 tutorial
Simple, fast, and scalable torch7 tutorialSimple, fast, and scalable torch7 tutorial
Simple, fast, and scalable torch7 tutorial
 

More from Chih-Hsuan Kuo

[ACM-ICPC] Tree Isomorphism
[ACM-ICPC] Tree Isomorphism[ACM-ICPC] Tree Isomorphism
[ACM-ICPC] Tree Isomorphism
Chih-Hsuan Kuo
 
[ACM-ICPC] Dinic's Algorithm
[ACM-ICPC] Dinic's Algorithm[ACM-ICPC] Dinic's Algorithm
[ACM-ICPC] Dinic's Algorithm
Chih-Hsuan Kuo
 
[ACM-ICPC] Disjoint Set
[ACM-ICPC] Disjoint Set[ACM-ICPC] Disjoint Set
[ACM-ICPC] Disjoint Set
Chih-Hsuan Kuo
 
[ACM-ICPC] Efficient Algorithm
[ACM-ICPC] Efficient Algorithm[ACM-ICPC] Efficient Algorithm
[ACM-ICPC] Efficient Algorithm
Chih-Hsuan Kuo
 
[ACM-ICPC] Top-down & Bottom-up
[ACM-ICPC] Top-down & Bottom-up[ACM-ICPC] Top-down & Bottom-up
[ACM-ICPC] Top-down & Bottom-up
Chih-Hsuan Kuo
 

More from Chih-Hsuan Kuo (20)

Rust
RustRust
Rust
 
[Mozilla] content-select
[Mozilla] content-select[Mozilla] content-select
[Mozilla] content-select
 
Necko walkthrough
Necko walkthroughNecko walkthrough
Necko walkthrough
 
Protocol handler in Gecko
Protocol handler in GeckoProtocol handler in Gecko
Protocol handler in Gecko
 
面試面試面試,因為很重要所以要說三次!
面試面試面試,因為很重要所以要說三次!面試面試面試,因為很重要所以要說三次!
面試面試面試,因為很重要所以要說三次!
 
應徵軟體工程師
應徵軟體工程師應徵軟體工程師
應徵軟體工程師
 
面試心得分享
面試心得分享面試心得分享
面試心得分享
 
Windows 真的不好用...
Windows 真的不好用...Windows 真的不好用...
Windows 真的不好用...
 
Python @Wheel Lab
Python @Wheel LabPython @Wheel Lab
Python @Wheel Lab
 
Introduction to VP8
Introduction to VP8Introduction to VP8
Introduction to VP8
 
Python @NCKU CSIE
Python @NCKU CSIEPython @NCKU CSIE
Python @NCKU CSIE
 
[ACM-ICPC] Tree Isomorphism
[ACM-ICPC] Tree Isomorphism[ACM-ICPC] Tree Isomorphism
[ACM-ICPC] Tree Isomorphism
 
[ACM-ICPC] Dinic's Algorithm
[ACM-ICPC] Dinic's Algorithm[ACM-ICPC] Dinic's Algorithm
[ACM-ICPC] Dinic's Algorithm
 
[ACM-ICPC] Disjoint Set
[ACM-ICPC] Disjoint Set[ACM-ICPC] Disjoint Set
[ACM-ICPC] Disjoint Set
 
[ACM-ICPC] Traversal
[ACM-ICPC] Traversal[ACM-ICPC] Traversal
[ACM-ICPC] Traversal
 
[ACM-ICPC] UVa-10245
[ACM-ICPC] UVa-10245[ACM-ICPC] UVa-10245
[ACM-ICPC] UVa-10245
 
[ACM-ICPC] Sort
[ACM-ICPC] Sort[ACM-ICPC] Sort
[ACM-ICPC] Sort
 
[ACM-ICPC] Efficient Algorithm
[ACM-ICPC] Efficient Algorithm[ACM-ICPC] Efficient Algorithm
[ACM-ICPC] Efficient Algorithm
 
[ACM-ICPC] Top-down & Bottom-up
[ACM-ICPC] Top-down & Bottom-up[ACM-ICPC] Top-down & Bottom-up
[ACM-ICPC] Top-down & Bottom-up
 
[ACM-ICPC] About I/O
[ACM-ICPC] About I/O[ACM-ICPC] About I/O
[ACM-ICPC] About I/O
 

Recently uploaded

Histor y of HAM Radio presentation slide
Histor y of HAM Radio presentation slideHistor y of HAM Radio presentation slide
Histor y of HAM Radio presentation slide
vu2urc
 
Artificial Intelligence: Facts and Myths
Artificial Intelligence: Facts and MythsArtificial Intelligence: Facts and Myths
Artificial Intelligence: Facts and Myths
Joaquim Jorge
 

Recently uploaded (20)

Data Cloud, More than a CDP by Matt Robison
Data Cloud, More than a CDP by Matt RobisonData Cloud, More than a CDP by Matt Robison
Data Cloud, More than a CDP by Matt Robison
 
Slack Application Development 101 Slides
Slack Application Development 101 SlidesSlack Application Development 101 Slides
Slack Application Development 101 Slides
 
Apidays Singapore 2024 - Building Digital Trust in a Digital Economy by Veron...
Apidays Singapore 2024 - Building Digital Trust in a Digital Economy by Veron...Apidays Singapore 2024 - Building Digital Trust in a Digital Economy by Veron...
Apidays Singapore 2024 - Building Digital Trust in a Digital Economy by Veron...
 
Boost PC performance: How more available memory can improve productivity
Boost PC performance: How more available memory can improve productivityBoost PC performance: How more available memory can improve productivity
Boost PC performance: How more available memory can improve productivity
 
Histor y of HAM Radio presentation slide
Histor y of HAM Radio presentation slideHistor y of HAM Radio presentation slide
Histor y of HAM Radio presentation slide
 
Handwritten Text Recognition for manuscripts and early printed texts
Handwritten Text Recognition for manuscripts and early printed textsHandwritten Text Recognition for manuscripts and early printed texts
Handwritten Text Recognition for manuscripts and early printed texts
 
Finology Group – Insurtech Innovation Award 2024
Finology Group – Insurtech Innovation Award 2024Finology Group – Insurtech Innovation Award 2024
Finology Group – Insurtech Innovation Award 2024
 
Artificial Intelligence: Facts and Myths
Artificial Intelligence: Facts and MythsArtificial Intelligence: Facts and Myths
Artificial Intelligence: Facts and Myths
 
Scaling API-first – The story of a global engineering organization
Scaling API-first – The story of a global engineering organizationScaling API-first – The story of a global engineering organization
Scaling API-first – The story of a global engineering organization
 
Tata AIG General Insurance Company - Insurer Innovation Award 2024
Tata AIG General Insurance Company - Insurer Innovation Award 2024Tata AIG General Insurance Company - Insurer Innovation Award 2024
Tata AIG General Insurance Company - Insurer Innovation Award 2024
 
2024: Domino Containers - The Next Step. News from the Domino Container commu...
2024: Domino Containers - The Next Step. News from the Domino Container commu...2024: Domino Containers - The Next Step. News from the Domino Container commu...
2024: Domino Containers - The Next Step. News from the Domino Container commu...
 
08448380779 Call Girls In Diplomatic Enclave Women Seeking Men
08448380779 Call Girls In Diplomatic Enclave Women Seeking Men08448380779 Call Girls In Diplomatic Enclave Women Seeking Men
08448380779 Call Girls In Diplomatic Enclave Women Seeking Men
 
🐬 The future of MySQL is Postgres 🐘
🐬  The future of MySQL is Postgres   🐘🐬  The future of MySQL is Postgres   🐘
🐬 The future of MySQL is Postgres 🐘
 
Axa Assurance Maroc - Insurer Innovation Award 2024
Axa Assurance Maroc - Insurer Innovation Award 2024Axa Assurance Maroc - Insurer Innovation Award 2024
Axa Assurance Maroc - Insurer Innovation Award 2024
 
Presentation on how to chat with PDF using ChatGPT code interpreter
Presentation on how to chat with PDF using ChatGPT code interpreterPresentation on how to chat with PDF using ChatGPT code interpreter
Presentation on how to chat with PDF using ChatGPT code interpreter
 
Workshop - Best of Both Worlds_ Combine KG and Vector search for enhanced R...
Workshop - Best of Both Worlds_ Combine  KG and Vector search for  enhanced R...Workshop - Best of Both Worlds_ Combine  KG and Vector search for  enhanced R...
Workshop - Best of Both Worlds_ Combine KG and Vector search for enhanced R...
 
Understanding Discord NSFW Servers A Guide for Responsible Users.pdf
Understanding Discord NSFW Servers A Guide for Responsible Users.pdfUnderstanding Discord NSFW Servers A Guide for Responsible Users.pdf
Understanding Discord NSFW Servers A Guide for Responsible Users.pdf
 
GenCyber Cyber Security Day Presentation
GenCyber Cyber Security Day PresentationGenCyber Cyber Security Day Presentation
GenCyber Cyber Security Day Presentation
 
08448380779 Call Girls In Greater Kailash - I Women Seeking Men
08448380779 Call Girls In Greater Kailash - I Women Seeking Men08448380779 Call Girls In Greater Kailash - I Women Seeking Men
08448380779 Call Girls In Greater Kailash - I Women Seeking Men
 
The Role of Taxonomy and Ontology in Semantic Layers - Heather Hedden.pdf
The Role of Taxonomy and Ontology in Semantic Layers - Heather Hedden.pdfThe Role of Taxonomy and Ontology in Semantic Layers - Heather Hedden.pdf
The Role of Taxonomy and Ontology in Semantic Layers - Heather Hedden.pdf
 

Effective Modern C++ - Item 35 & 36

  • 1. Item 35: Prefer task-based programming to thread-based. Item 36: Specify std::launch::async if asynchronicity is essential. BE RATIONAL, NOT SOUR. Tommy Kuo [:KuoE0] kuoe0@mozilla.com Effective Modern C++
  • 2. Item 35: Prefer task-based programming to thread-based.
  • 3. Concurrency in C++11 int doAsyncWork(); // thread-based programming std::thread t(doAsyncWork); // task-based programming auto fut = std::async(doAsyncWork); std::future<int>
  • 4. Return Valueuse get() to get the return value std::async function std::future object return int fib(int x) { return x <= 2 ? x - 1 : fib(x - 1) + fib(x - 2); } int main() { auto fut = std::async(fib, 40); auto ret = fut.get(); std::cout << ret << std::endl; return 0; } std::future::get function call
  • 5. Handle Erroruse get() to throw exceptions std::async function std::future object return int fib(int x) { if (x < 1) throw logic_error("Don't you know Fibonacci?"); return x <= 2 ? x - 1 : fib(x - 1) + fib(x - 2); } int main() { auto fut = async(fib, 0); try { cout << fut.get() << endl; } catch(exception& e) { cout << e.what() << endl; } return 0; } std::future::get function call throw exception
  • 6. Handle Error with std::thread int fib(int x) { if (x < 1) throw logic_error("Don't you know Fibonacci?"); return x <= 2 ? x - 1 : fib(x - 1) + fib(x - 2); } int main() { try { auto t = thread(fib, 0); } catch(exception& e) { cout << e.what() << endl; } return 0; } throw exception
  • 8. Nightmare with Thread Management (thread exhaustion) system provides 6 threads. int main() { std::vector<std::thread> thread_pool(1000); return 0; } throw std::system_error exception more than system can provide
  • 9. Nightmare with Thread Management (oversubscription) CPU provides 2 threads system has 100 threads ready to run × 100 oversubscription
  • 10. Nightmare with Thread Management (oversubscription) CPU provides 2 threads system has 100 threads ready to run × 100 Context switches increase the overall thread management overhead of the system. oversubscription
  • 11. – Effective Modern C++, Scott Meyer “Your life will be easier if you dump these problems on somebody else, and using std::async.”
  • 12. std::async takes responsibility for thread management. #1, running task 1 #2, running task 2 #3, empty task 3 task 4 task 5 task 6 task 7 task queue Discuss in item 36 later :)
  • 13. BUT
  • 14. When to Use std::thread - Need access to the API of the underlying threading implementation. Using std::thread::native_handle to get the lower-level platform- specific thread (pthreads or Windows’ Threads). - Need to and are able to optimize thread usage. - Need to implement threading technology beyond the C++ concurrency API.
  • 15. Things to Remember - The std::thread API offers no direct way to get return values from asynchronously run functions, and if those functions throw, the program is terminated. - Thread-based programming calls for manual management of thread exhaustion, oversubscription, load balancing, and adaptation to new platforms. - Task-based programming via std::async with the default launch policy handles most of these issues for you.
  • 16. Item 36: Specify std::launch::async if asynchronicity is essential.
  • 17. Launch Policy of std::async - std::launch::async Task must be run asynchronously. - std::launch::deferred Task may run only when get or wait is called on the future returned by std::async.
  • 18. You have to present on 2016/01/06. 2015/10/01 2015/10/01 Junior Done. 😎 2015/10/02 2016/01/05 I hope I can finish it before Wednesday. 😭 You have to present on 2016/01/06. Junior Tommy (with async-driven) Tommy (with deferred-driven) behavior of async policy behavior of deferred policy OK! 😎 Tommy (with async-driven) OK! 😎 Tommy (with async-driven) Are you ready? Junior Are you ready? Junior
  • 19. Default Launch Policy auto fut = std::async(task); // create with default launch policy auto fut = std::async(std::launch::async | std::launch::deferred, task); // as same as the default launch policy The default policy thus permits tasks to be run either asynchronously or synchronously.
  • 20. - Not possible to predict whether tasks will run concurrently. - Not possible to predict whether tasks run on a thread different from the thread invoking get or wait. - May not be possible to predict whether tasks run at all.
  • 21. std::async(task) async policy deferred policy looks good! thread_local variables timeout-based wait affect
  • 22. With deferred policy, thread_local variables will act as normal global variables.
  • 23. thread_local variables with async policy thread_local int x = 0; int func(bool update, int val){ return update ? x = val : x; } int main(){ x = 9; std::future<int> task[4]; for (int i = 0; i < 3; ++i) task[i] = std::async(std::launch::async, func, true, i + 1); task[3] = std::async(std::launch::async, func, false, 0); for (auto& t: task) std::cout << t.get(); std::cout << x << std::endl; return 0; }
  • 24. thread_local variables with async policy thread_local int x = 0; int func(bool update, int val){ return update ? x = val : x; } int main(){ x = 9; std::future<int> task[4]; for (int i = 0; i < 3; ++i) task[i] = std::async(std::launch::async, func, true, i + 1); task[3] = std::async(std::launch::async, func, false, 0); for (auto& t: task) std::cout << t.get(); std::cout << x << std::endl; return 0; } output —————————————————————— 12309
  • 25. thread_local variables with deferred policy thread_local int x = 0; int func(bool update, int val){ return update ? x = val : x; } int main(){ x = 9; std::future<int> task[4]; for (int i = 0; i < 3; ++i) task[i] = std::async(std::launch::deferred, func, true, i + 1); task[3] = std::async(std::launch::deferred, func, false, 0); for (auto& t: task) std::cout << t.get(); std::cout << x << std::endl; return 0; }
  • 26. thread_local variables with deferred policy thread_local int x = 0; int func(bool update, int val){ return update ? x = val : x; } int main(){ x = 9; std::future<int> task[4]; for (int i = 0; i < 3; ++i) task[i] = std::async(std::launch::deferred, func, true, i + 1); task[3] = std::async(std::launch::deferred, func, false, 0); for (auto& t: task) std::cout << t.get(); std::cout << x << std::endl; return 0; } output —————————————————————— 12333
  • 27. With deferred policy, wait_for and wait_until will return std::future_status::deferred.
  • 28. Infinite-loop problem with timeout-based wait int main() { auto fut = std::async(std::launch::deferred, task); // deferred policy while (fut.wait_for(100ms) != std::future_status::ready) { std::cout << “waiting…” << std::endl; } std::cout << fut.get() << std::endl; return 0; } return std::future_status::deferred always
  • 29. Resolve infinite-loop problem int main() { auto fut = std::async(task); // deferred policy if (fut.wait_for(0ms) == std::future_status::deferred) { fut.wait(); // fut.get() also works. } else { while (fut.wait_for(100ms) != std::future_status::ready) { std::cout << “waiting…” << std::endl; } } std::cout << fut.get() << std::endl; return 0; } check it and make it run synchronously
  • 30. BUT
  • 31. When to Use Default Launch Policy - The task need not run concurrently with the thread calling get or wait. 
 - It doesn’t matter which thread’s thread_local variables are read or written. 
 - Either there’s a guarantee that get or wait will be called on the future returned by std::async. - It’s acceptable that the task may never execute. - Code using wait_for or wait_until takes the possibility of deferred status into account.
  • 32. Function to Use Async Policy (C++11) template<typename F, typename... Ts> inline std::future<typename std::result_of<F(Ts…)>::type> reallyAsync(F&& f, Ts&&... params) { return std::async(std::launch::async, std::forward<F>(f), std::forward<Ts>(params)…); }
  • 33. Function to Use Async Policy (C++14) template<typename F, typename... Ts> inline auto reallyAsync(F&& f, Ts&&... params) { return std::async(std::launch::async, std::forward<F>(f), std::forward<Ts>(params)…); }
  • 34. Things to Remember - The default launch policy for std::async permits both asynchronous and synchronous task execution. - This flexibility leads to uncertainty when accessing thread_local variables, implies that the task may never execute, and affects program logic for timeout-based wait calls. - Specify std::launch::async if asynchronous task execution is essential.