From 87ce8e2ae457c7e102562ef3a45bba1374b1fe90 Mon Sep 17 00:00:00 2001
From: Andreas Messerschmid <andreas@linutronix.de>
Date: Tue, 2 Jun 2015 08:06:53 +0200
Subject: C++-Threading overview paper added

---
 application-devel/c++/pres_c++-threads.tex | 216 +++++++++++++++++++++++++++++
 1 file changed, 216 insertions(+)
 create mode 100644 application-devel/c++/pres_c++-threads.tex

(limited to 'application-devel/c++/pres_c++-threads.tex')

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}
-- 
cgit v1.2.3

