summaryrefslogtreecommitdiff
path: root/application-devel/c++/pres_c++-threads.tex
diff options
context:
space:
mode:
authorAndreas Messerschmid <andreas@linutronix.de>2015-06-02 08:06:53 +0200
committerAndreas Messerschmid <andreas@linutronix.de>2015-06-02 08:06:53 +0200
commit87ce8e2ae457c7e102562ef3a45bba1374b1fe90 (patch)
tree0c9ee3c921f70cf6ef0a942669835d4ec22a8d73 /application-devel/c++/pres_c++-threads.tex
parentae871ff78216eac34cd97679315a3ff8daac4d6c (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.tex216
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}