Reference documentation for deal.II version 9.3.3
\(\newcommand{\dealvcentcolon}{\mathrel{\mathop{:}}}\) \(\newcommand{\dealcoloneq}{\dealvcentcolon\mathrel{\mkern-1.2mu}=}\) \(\newcommand{\jump}[1]{\left[\!\left[ #1 \right]\!\right]}\) \(\newcommand{\average}[1]{\left\{\!\left\{ #1 \right\}\!\right\}}\)
Public Member Functions | Public Attributes | Static Private Member Functions | List of all members
Threads::internal::ThreadDescriptor< RT > Struct Template Reference

#include <deal.II/base/thread_management.h>

Inheritance diagram for Threads::internal::ThreadDescriptor< RT >:
[legend]

Public Member Functions

 ThreadDescriptor ()
 
 ~ThreadDescriptor ()
 
void start (const std::function< RT()> &function)
 
void join ()
 

Public Attributes

std::thread thread
 
std::shared_ptr< return_value< RT > > ret_val
 
std::atomic< boolthread_is_active
 
Mutex thread_is_active_mutex
 

Static Private Member Functions

static void thread_entry_point (const std::function< RT()> &function, std::shared_ptr< return_value< RT > > ret_val)
 

Detailed Description

template<typename RT>
struct Threads::internal::ThreadDescriptor< RT >

A class that represents threads. For each thread, we create exactly one of these objects – exactly one because it carries the returned value of the function called on the thread.

While we have only one of these objects per thread, several Threads::Thread objects may refer to this descriptor. If all Thread objects go out of scope the ThreadDescriptor will detach from the thread before being destroyed.

Definition at line 415 of file thread_management.h.

Constructor & Destructor Documentation

◆ ThreadDescriptor()

template<typename RT >
Threads::internal::ThreadDescriptor< RT >::ThreadDescriptor ( )
inline

Default constructor.

Definition at line 477 of file thread_management.h.

◆ ~ThreadDescriptor()

template<typename RT >
Threads::internal::ThreadDescriptor< RT >::~ThreadDescriptor ( )
inline

Definition at line 481 of file thread_management.h.

Member Function Documentation

◆ start()

template<typename RT >
void Threads::internal::ThreadDescriptor< RT >::start ( const std::function< RT()> &  function)
inline

Start the thread and let it put its return value into the ret_val object.

Definition at line 494 of file thread_management.h.

◆ join()

template<typename RT >
void Threads::internal::ThreadDescriptor< RT >::join ( )
inline

Wait for the thread to end.

Definition at line 506 of file thread_management.h.

◆ thread_entry_point()

template<typename RT >
static void Threads::internal::ThreadDescriptor< RT >::thread_entry_point ( const std::function< RT()> &  function,
std::shared_ptr< return_value< RT > >  ret_val 
)
inlinestaticprivate

The function that runs on the thread.

Definition at line 528 of file thread_management.h.

Member Data Documentation

◆ thread

template<typename RT >
std::thread Threads::internal::ThreadDescriptor< RT >::thread

An object that represents the thread started.

Definition at line 420 of file thread_management.h.

◆ ret_val

template<typename RT >
std::shared_ptr<return_value<RT> > Threads::internal::ThreadDescriptor< RT >::ret_val

An object that will hold the value returned by the function called on the thread.

The return value is stored in a shared_ptr because we might abandon the ThreadDescriptor. This makes sure the object stays alive until the thread exits.

Definition at line 430 of file thread_management.h.

◆ thread_is_active

template<typename RT >
std::atomic<bool> Threads::internal::ThreadDescriptor< RT >::thread_is_active

An atomic bool variable that is initially false, is set to true when a new thread is started, and is set back to false once join() has been called.

We use this variable to make sure we can call join() twice on the same thread. For some reason, the C++ standard library throws a std::system_error exception if one tries to call std::thread::join twice (and in fact, before the second call, std::thread::joinable returns false) but this is a somewhat desirable thing to do because one doesn't have to keep track whether join() has been called before. Using this variable, whenever we have called join() before, the variable is set to true and we can skip over calling std::thread::join() a second time. Access to this variable is guarded by the following mutex.

Note
Historically, we did not need the mutex for this variable: threads can only be joined from the thread that created it originally. Consequently, everything that happens in a function that does not create threads (such as the join() function below) looks atomic to the outside world. Since we clear and test thread_is_active in the same function as we call std::thread::join, these actions are atomic and need no mutex. Of course, two threads may call join() on the same thread object at the same time, but this action is undefined anyway since they can not both join the same thread. That said, more recent C++ standards do not appear to have the requirement any more that the only thread that can call join() is the one that created the thread. Neither does pthread_join appear to have this requirement any more. Consequently, we can in fact join from different threads and we test this in base/thread_validity_07.
The reason why we need to use a std::atomic<bool> is discussed in detail in the documentation of Task::task_has_finished.

Definition at line 467 of file thread_management.h.

◆ thread_is_active_mutex

template<typename RT >
Mutex Threads::internal::ThreadDescriptor< RT >::thread_is_active_mutex

Mutex guarding access to the previous variable.

Definition at line 472 of file thread_management.h.


The documentation for this struct was generated from the following file: