Pigweed
Loading...
Searching...
No Matches
pw::thread::Thread Class Reference

#include <thread.h>

Public Types

using native_handle_type = backend::NativeThreadHandle
 
using ThreadRoutine = void(*)(void *arg)
 

Public Member Functions

 Thread ()
 
 Thread (const Options &options, Function< void()> &&entry)
 
 Thread (const Options &options, ThreadCore &thread_core)
 
 Thread (const Options &options, ThreadRoutine entry, void *arg=nullptr)
 
Threadoperator= (Thread &&other)
 
 ~Thread ()
 Precondition: The thread must have been EITHER detached or joined.
 
 Thread (const Thread &)=delete
 
 Thread (Thread &&)=delete
 
Threadoperator= (const Thread &)=delete
 
Id get_id () const
 
bool joinable () const
 
template<typename kUnusedType = void>
void join ()
 
void detach ()
 
void swap (Thread &other)
 Exchanges the underlying handles of two thread objects.
 
native_handle_type native_handle ()
 

Detailed Description

The class Thread can represent a single thread of execution. Threads allow multiple functions to execute concurrently.

Threads may begin execution immediately upon construction of the associated thread object (pending any OS scheduling delays), starting at the top-level function provided as a constructor argument. The return value of the top-level function is ignored. The top-level function may communicate its return value by modifying shared variables (which may require synchronization, see pw_sync and std::atomic)

Thread objects may also be in the state that does not represent any thread (after default construction, move from, detach, or join), and a thread of execution may be not associated with any thread objects (after detach).

No two Thread objects may represent the same thread of execution; Thread is not CopyConstructible or CopyAssignable, although it is MoveConstructible and MoveAssignable.

Member Typedef Documentation

◆ native_handle_type

using pw::thread::Thread::native_handle_type = backend::NativeThreadHandle

The type of the native handle for the thread. As with std::thread, use is inherently non-portable.

Constructor & Destructor Documentation

◆ Thread() [1/4]

pw::thread::Thread::Thread ( )

Creates a new thread object which does not represent a thread of execution yet.

◆ Thread() [2/4]

pw::thread::Thread::Thread ( const Options options,
Function< void()> &&  entry 
)

Creates a thread from a void-returning function or lambda.

This function accepts any callable (including lambdas) which returns void. When using a lambda, the captures must not exceed the inline size of pw::Function (usually a single pointer) unless dynamic allocation is enabled.

To invoke a member method of a class a static lambda closure can be used to ensure the dispatching closure is not destructed before the thread is done executing. For example:

class Foo {
public:
void DoBar() {}
};
Foo foo;
// Now use the lambda closure as the thread entry, passing the foo's
// this as the argument.
Thread thread(options, [&foo]() { foo.DoBar(); });
thread.detach();

Alternatively a helper ThreadCore interface can be implemented by an object so that a lambda closure or function is not needed to dispatch to a member function without arguments. For example:

Postcondition: The thread get EITHER detached or joined.

NOTE: Options have a default constructor, however default options are not portable! Default options can only work if threads are dynamically allocated by default, meaning default options cannot work on backends which require static thread allocations. In addition on some schedulers default options may not work for other reasons.

◆ Thread() [3/4]

pw::thread::Thread::Thread ( const Options options,
ThreadCore &  thread_core 
)

Creates a thread from a ThreadCore subclass.

The ThreadCore interface can be implemented by an object so that a lambda closure or function is not needed to dispatch to a member function.

For example:

class Foo : public ThreadCore {
private:
void Run() override {}
};
Foo foo;
// Now create the thread, using foo directly.
Thread(options, foo).detach();

Postcondition: The thread get EITHER detached or joined.

NOTE: Options have a default constructor, however default options are not portable! Default options can only work if threads are dynamically allocated by default, meaning default options cannot work on backends which require static thread allocations. In addition on some schedulers default options may not work for other reasons.

◆ Thread() [4/4]

pw::thread::Thread::Thread ( const Options options,
ThreadRoutine  entry,
void *  arg = nullptr 
)

DEPRECATED: Creates a thread from a void-returning function pointer and a void pointer argument.

Postcondition: The thread get EITHER detached or joined.

NOTE: Options have a default constructor, however default options are not portable! Default options can only work if threads are dynamically allocated by default, meaning default options cannot work on backends which require static thread allocations. In addition on some schedulers default options may not work for other reasons.

Member Function Documentation

◆ detach()

void pw::thread::Thread::detach ( )

Separates the thread of execution from the thread object, allowing execution to continue independently. Any allocated resources will be freed once the thread exits.

Precondition: The thread must have been NEITHER detached nor joined.

Postcondition: After calling detach *this no longer owns any thread.

◆ get_id()

Id pw::thread::Thread::get_id ( ) const

Returns a value of Thread::id identifying the thread associated with *this. If there is no thread associated, default constructed Thread::id is returned.

◆ joinable()

bool pw::thread::Thread::joinable ( ) const
inline

Checks if the Thread object identifies an active thread of execution which has not yet been detached. Specifically, returns true if get_id() != pw::Thread::id() && detach() has NOT been invoked. So a default constructed thread is not joinable and neither is one which was detached.

A thread that has not started or has finished executing code which was never detached, but has not yet been joined is still considered an active thread of execution and is therefore joinable.

◆ native_handle()

native_handle_type pw::thread::Thread::native_handle ( )

Returns the native handle for the thread. As with std::thread, use is inherently non-portable.

◆ operator=()

Thread & pw::thread::Thread::operator= ( Thread &&  other)

Postcondition: The other thread no longer represents a thread of execution.


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