diff options
| author | Andreas Messerschmid <andreas@linutronix.de> | 2015-06-02 08:06:53 +0200 |
|---|---|---|
| committer | Andreas Messerschmid <andreas@linutronix.de> | 2015-06-02 08:06:53 +0200 |
| commit | 87ce8e2ae457c7e102562ef3a45bba1374b1fe90 (patch) | |
| tree | 0c9ee3c921f70cf6ef0a942669835d4ec22a8d73 /application-devel/c++/pres_c++-threads.tex | |
| parent | ae871ff78216eac34cd97679315a3ff8daac4d6c (diff) | |
C++-Threading overview paper added
Diffstat (limited to 'application-devel/c++/pres_c++-threads.tex')
| -rw-r--r-- | application-devel/c++/pres_c++-threads.tex | 216 |
1 files changed, 216 insertions, 0 deletions
diff --git a/application-devel/c++/pres_c++-threads.tex b/application-devel/c++/pres_c++-threads.tex new file mode 100644 index 0000000..a46717a --- /dev/null +++ b/application-devel/c++/pres_c++-threads.tex @@ -0,0 +1,216 @@ +\input{configpres} + +\def\lximg{/usr/share/lx/icons/fueller.png} + +\subsection{C++ Threads} + +\title{Threading in C++} +\maketitle + +% stop displaying 'fueller.png' on the following slides +\def\lximg{none} + +%\begin{frame} +% \tableofcontents +%\end{frame} + +\subsubsection{Threading} +\begin{frame} +\frametitle{Threads in C++} +\begin{itemize} +\item Platform independet concurrency available since C++11 +\item Prior to C++11: platform-specific extensions like OpenMP, PThreads +\item Classes for thread management, manipulation and synchronisation +\end{itemize} +\end{frame} + +\begin{frame}[fragile] +\frametitle{C++ Thread Management} +Creating and starting a thread: +\begin{lstlisting} +#include <iostream> +#include <thread> + +void thread_fn() +{ + std::cout << "This output was generated in a thread." << std::endl; +} + +int main() +{ + std::thread my_thread(thread_fn); // instantiate thread object + + my_thread.join(); // wait for my_thread to finish +} +\end{lstlisting} +\end{frame} + +\begin{frame}[fragile] +\frametitle{C++ Thread Management} +Passing parameters to a thread function: +\begin{lstlisting} +#include <iostream> +#include <thread> + +void thread_add(int a, int b) +{ + int c = a + b; + + std::cout << "Addition result: " << c << std::endl; +} + + +int main() +{ + std::thread my_thread_add(thread_add, 10, 20); + + my_thread_add.join(); // wait for addition to finish +} +\end{lstlisting} +\end{frame} + +\subsubsection{Synchronisation} +\begin{frame} +\frametitle{Synchronisation Mechanisms} +\begin{itemize} +\item Synchronisation of threads is mandatory +\item Basic synchronisation primitives: +\begin{itemize} +\item mutex objects +\item condition variables +\end{itemize} +\item Advanced synchronisation primitives: +\begin{itemize} +\item futures +\item atomics +\end{itemize} +\end{itemize} +\end{frame} + +\begin{frame}[fragile] +\frametitle{Mutex} +Using mutex objects: +\begin{lstlisting} +#include <mutex> + +std::mutex my_mutex; +unsigned int up_counter = 0; + +unsigned int counter_inc() +{ + std::lock_guard<std::mutex> lock(my_mutex); + return ++up_counter; +} + +unsigned int counter_read() +{ + std::lock_guard<std::mutex> lock(my_mutex); + return up_counter; +} +\end{lstlisting} +Using direct calls to the methods lock() and unlock() is possible too. +We must ensure to unlock the mutex at each exit from protected regions +including the launch of exceptions. So it's more safe to to use the +lockguard template! +\end{frame} + +\begin{frame}[fragile] +\frametitle{Condition variables} +Using condition variables: +\begin{lstlisting} +#include <condition_variable> + +std::mutex m; std::condition_variable cv; bool processed = false; + +void thread_fn() +{ + processed = true; + std::cout << "Thread signals data processing completed\n"; + cv.notify_one(); +} + +int main() +{ + std::thread my_thread(thread_fn); + std::unique_lock<std::mutex> lk(m); + cv.wait(lk, []{return processed;}); + if(processed) + std::cout << "Main thread got the signal\n"; + else + std::cout << "Oops, something went wrong\n"; + my_thread.join(); +} +\end{lstlisting} +\end{frame} + +\begin{frame}[fragile] +\frametitle{Futures} +Futures are used to launch asynchronous operations whose results are +not required immediately. +\begin{lstlisting} +#include <future> + +int long_time_computation() +{ + int a = 5, b = 3; + + return a + b; +} + +void do_other_stuff() +{ + std::cout << "We print this while long_time_computation is ongoing\n"; +} + +int main() +{ + std::future<int> the_result = std::async(long_time_computation); + + do_other_stuff(); + + std::cout << "The result is " << the_result.get() << std::endl; +} +\end{lstlisting} +\end{frame} + +\begin{frame}[fragile] +\frametitle{Atomics} +\begin{verbatim} +#include <atomic> + +std::atomic<int> counter = 1; +counter++; +\end{verbatim} +\begin{itemize} +\item An atomic type can be used with any template T type +\item Operations on atomics will be executed in its entirety or not at all +\item Good performance due to lock free implementation +\end{itemize} +\end{frame} + +\subsubsection{C++-Threads going realtime} + +\begin{frame}[fragile] +\frametitle{C++-Threads going realtime} +C++-Threads can be brought to realtime context using the PThread-API +\begin{lstlisting} +#include <thread> +#include <pthread.h> + +int main() +{ + std::thread my_thread; + sched_param sch; + int policy; + + pthread_getschedparam(my_thread.native_handle(), &policy, &sch); + sch.sched_priority = 20; + if(pthread_setschedparam(my_thread.native_handle(), SCHED_FIFO, &sch)) + { + std::cout << "Failure: " << std::strerror(errno) << std::endl; + } +} +\end{lstlisting} +\end{frame} + +\input{tailpres} |
