PCL
pcl::Thread Class Reference

Client-side interface to a PixInsight thread. More...

#include <Thread.h>

+ Inheritance diagram for pcl::Thread:

Public Types

using priority = ThreadPriority::value_type
 

Public Member Functions

 Thread ()
 
 ~Thread () override
 
void Abort ()
 
Array< int > Affinity () const
 
void ClearConsoleOutputText ()
 
String ConsoleOutputText () const
 
void EnsureUnique () override
 
void FlushConsoleOutputText ()
 
bool HasConsoleOutputText () const
 
bool IsAborted () const
 
bool IsActive () const
 
void Kill ()
 
priority Priority () const
 
void ResetPriority ()
 
virtual void Run ()
 
bool SetAffinity (const Array< int > &processors)
 
bool SetAffinity (int processor)
 
void SetPriority (priority)
 
void SetStatus (uint32 status)
 
void Sleep (unsigned ms)
 
void Start (priority=ThreadPriority::Inherit, int processor=-1)
 
uint32 Status () const
 
bool TryGetStatus (uint32 &status) const
 
bool TryIsAborted () const
 
void Wait ()
 
bool Wait (unsigned ms)
 
- Public Member Functions inherited from pcl::UIObject
virtual ~UIObject () noexcept(false)
 
bool IsAlias () const
 
bool IsGarbage () const
 
bool IsNull () const
 
bool IsSameObject (const UIObject &o) const
 
bool IsUnique () const
 
String ObjectId () const
 
IsoString ObjectType () const
 
bool operator< (const UIObject &o) const
 
bool operator== (const UIObject &o) const
 
size_type RefCount () const
 
void SetObjectId (const String &id)
 

Static Public Member Functions

static bool IsRootThread ()
 
static ThreadNull ()
 
static int NumberOfRunningThreads ()
 
static int NumberOfThreads (size_type count, size_type overheadLimit=1u)
 
static Array< size_typeOptimalThreadLoads (size_type count, size_type overheadLimit=1u, int maxThreads=PCL_MAX_PROCESSORS)
 
static Array< size_typeOptimalThreadLoadsAligned (size_type count, int align=16, size_type overheadLimit=1u, int maxThreads=PCL_MAX_PROCESSORS)
 
- Static Public Member Functions inherited from pcl::UIObject
static UIObjectNull ()
 

Additional Inherited Members

- Protected Member Functions inherited from pcl::UIObject
 UIObject ()=default
 
 UIObject (const UIObject &x)
 
 UIObject (UIObject &&x)
 
UIObjectoperator= (const UIObject &x)
 
UIObjectoperator= (UIObject &&x)
 

Detailed Description

TODO: Write a detailed description for Thread

Definition at line 129 of file Thread.h.

Member Typedef Documentation

◆ priority

using pcl::Thread::priority = ThreadPriority::value_type

Represents a thread priority.

Definition at line 136 of file Thread.h.

Constructor & Destructor Documentation

◆ Thread()

pcl::Thread::Thread ( )

Constructs a Thread object.

◆ ~Thread()

pcl::Thread::~Thread ( )
inlineoverride

Destroys a Thread object.

Definition at line 146 of file Thread.h.

Member Function Documentation

◆ Abort()

void pcl::Thread::Abort ( )
inline

Sends an abort message to a running thread.

If the thread calls Module->ProcessEvents() after an abort message has been sent, or if it uses some of the standard status monitoring classes (such as StandardStatus for example), a ProcessAborted exception will be thrown automatically in the thread. The exception will be thrown in the (reimplemented) Thread::Run() member function, where it should be caught and used to terminate thread execution by returning from Run(). This mechanism can be used to synchronize and stop running threads in a controlled and thread-safe way.

Note
A thread abort message means that the high-order bit of a running thread's status has been set. This member function simply sets the thread status to 0x80000000. To effectively abort the thread, it should call Module->ProcessEvents(), as described above, and should stop its execution after catching a ProcessAborted exception.
This member function is thread-safe. It can be safely called for a running thread, even from other running threads.

Definition at line 476 of file Thread.h.

◆ Affinity()

Array<int> pcl::Thread::Affinity ( ) const

Returns a set of processor indices corresponding to this thread's CPU affinity.

The affinity of a thread defines the set of logical processors on which the thread is eligible to run. Thread affinity allows to improve execution speed by restricting each thread to run on a separate processor. This prevents the performance cost caused by the cache invalidation that occurs when a process ceases to execute on one processor and then restarts execution on a different one (e.g. the infamous ping-pong effect).

If this thread is not running, this function returns the affinity of the calling thread.

Note
Currently, this function only works on Linux. On FreeBSD, Mac OS X and Windows platforms, this function always returns an empty array. We hope to overcome this limitation in a future version of PCL.

◆ ClearConsoleOutputText()

void pcl::Thread::ClearConsoleOutputText ( )

Erases the accumulated console output text in this thread.

For information on thread console output, refer to the documentation for the ConsoleOutputText() member function.

◆ ConsoleOutputText()

String pcl::Thread::ConsoleOutputText ( ) const

Returns the console output text currently accumulated in this thread.

When a Thread object is running (that is, when its IsActive() member function returns true), no operation on the graphical user interface is permitted from the thread. This includes console text output.

When a running thread writes text to the console, for example by calling Console::Write() or Console::WriteLn(), the text is not sent to the console (which in fact would raise an Error exception), but it is instead appended to the thread's console output text. The accumulated output text can be sent to the console once the thread has finished execution, or it can be retrieved by calling this member function.

◆ EnsureUnique()

void pcl::Thread::EnsureUnique ( )
inlineoverridevirtual

Ensures that the server-side object managed by this instance is uniquely referenced.

Since threads are unique objects by nature, calling this member function has no effect.

Reimplemented from pcl::UIObject.

Definition at line 157 of file Thread.h.

◆ FlushConsoleOutputText()

void pcl::Thread::FlushConsoleOutputText ( )

Sends any accumulated console output text in this thread to the console.

After writing the accumulated text to the console, this member function clears it, so that repeated calls to this function will have no effect.

For information on thread console output, refer to the documentation for the ConsoleOutputText() member function.

Note
This member function must only be called from the root thread. Calling it from a running Thread object has no effect.

◆ HasConsoleOutputText()

bool pcl::Thread::HasConsoleOutputText ( ) const
inline

Returns true iff this thread has any accumulated console output text that still has not been flushed or cleared.

For information on thread console output, refer to the documentation for the ConsoleOutputText() member function.

Definition at line 538 of file Thread.h.

◆ IsAborted()

bool pcl::Thread::IsAborted ( ) const
inline

Returns true iff this thread has been aborted. A thread has been aborted if it has received an abort message by a previous call to Abort(), or by setting the high-order bit of its thread status word.

Note
This member function is thread-safe. It can be safely called for a running thread.
This function calls Status() to read the current thread's status. Consequently, it blocks the caller's execution and has the same performance problems. For a non-blocking alternative, see TryIsAborted().

Definition at line 493 of file Thread.h.

◆ IsActive()

bool pcl::Thread::IsActive ( ) const

Returns true iff this thread is running.

◆ IsRootThread()

static bool pcl::Thread::IsRootThread ( )
static

This member function returns true if and only if it is called from the root thread. The root thread is the thread where the graphical user interface is running on the PixInsight core application.

Note
Since version 1.8.0 of the PixInsight core application, nested parallelism is fully supported. This means that multiple threads can be run by calling Thread::Start() from either the root thread or any running Thread object. In versions prior to 1.8.0, a thread could only be run from the root thread.

Referenced by pcl::AbstractImage::RunThreads().

◆ Kill()

void pcl::Thread::Kill ( )

Forces immediate termination of thread execution.

Warning
Calling this function is dangerous because it causes the immediate termination of a running thread without giving it a chance to perform any cleanup. For example, open files will not be closed, locked objects will not be unlocked, and shared static variables may be left at invalid states, with unpredictable results.
Calling this member function is strongly discouraged - Use it at your own risk

◆ Null()

static Thread& pcl::Thread::Null ( )
static

Returns a reference to a null Thread instance.

A null Thread does not correspond to an existing thread in the core PixInsight application.

◆ NumberOfRunningThreads()

static int pcl::Thread::NumberOfRunningThreads ( )
static

Returns the total number of running Thread objects.

Note
This function knows nothing about threads out of PCL control, so it will return zero if no Thread instance is currently active, even if there are other native threads being executed.

◆ NumberOfThreads()

static int pcl::Thread::NumberOfThreads ( size_type  count,
size_type  overheadLimit = 1u 
)
static

Returns the maximum number of threads that can be used concurrently to process a set of items.

Parameters
countNumber of processing units. A processing unit can be a single pixel, a row of pixels, or any suitable item, according to the task being performed by the caller.
overheadLimitThread overhead limit in processing units. The function returns a maximum number of threads such that no thread would have to process less processing units than this value. The default overhead limit is one processing unit.

This function takes into account the number of existing processors in the system, as well as the maximum number of processors currently allowed for external processes by the core application, and the number of threads currently active. The following global variables are taken into account (see the PixInsightSettings class for more information about global variables on the PixInsight platform):

Process/EnableParallelProcessing

If this global flag is false, it means that parallel processing has been globally disabled for the entire platform, so this function will always return one, irrespective of the number of existing processors.

Process/EnableParallelModuleProcessing

If this global flag is false, it means that parallel processing has been disabled for all installed modules, so this function will always return one, as in the previous case.

Process/MaxProcessors This global integer variable is the maximum number of processors allowed for installed modules, which is always less than or equal to the number of existing processors in the system. This function will never return a number of threads greater than the value of this variable.

The number of processors term refers to the number of existing logical processors in the system. These include all physical processors in multiprocessor systems, as well as all existing processor cores in multicore processors, and virtual processors in systems with HyperThreading or equivalent technology.

Since version 1.8.0 of the PixInsight core application, nested parallelism is fully supported. This means that multiple threads can be executed concurrently from a running thread. This function will take into account the number of already running threads, as provided by the Thread::NumberOfRunningThreads() static member function, to help prevent exceeding the maximum number of threads allowed by the platform (see the global variables in the table above). In any event, the calling module is entirely responsible to comply with these restrictions.

Note
A module must never try to run more threads concurrently than the amount returned by this function. Failure to follow this rule will invalidate a module for certification.

◆ OptimalThreadLoads()

static Array<size_type> pcl::Thread::OptimalThreadLoads ( size_type  count,
size_type  overheadLimit = 1u,
int  maxThreads = PCL_MAX_PROCESSORS 
)
static

Returns a list of per-thread counts optimized for parallel processing of a set of items.

Parameters
countNumber of processing units. A processing unit can be a single pixel, a row of pixels, or any suitable item, according to the task being performed by the caller.
overheadLimitThread overhead limit in processing units. The function returns a list with a maximum length such that no thread would have to process less processing units than this value. The default overhead limit is one processing unit.
maxThreadsMaximum number of threads to use. The length of the returned list will be at most either this value, or the maximum number of threads currently allowed for the calling process, whichever is less. The default value of this parameter does not impose a practical limit.

This function takes into account the number of existing logical processors in the system, as well as the maximum number of processors currently allowed for external processes by the PixInsight core application, and the number of threads currently active. See the NumberOfThreads() static member function for more information on thread execution and the global settings governing their use in PixInsight.

This function returns a dynamic array of unsigned integers, where each element is the number of items that the corresponding thread should process in order to make an optimal usage of the processor resources currently available. The length of the returned array is the maximum number of threads that the calling process should execute concurrently to process the specified number of items, with the specified overhead limit and maximum number of processors.

In the current implementation of this function, the returned array tends to spread the total work load uniformly across the threads available. Future implementations may consider additional factors, including the possibility of using new global settings specific for thread execution optimization. For this reason, under normal conditions a module should always use the result of calling this function to define a thread execution schedule. See also OptimalThreadLoadsAligned() for a variant of this function with prescribed item alignment.

Note
A module must never try to run more threads concurrently than the length of the array returned by this function. Failure to follow this rule will invalidate a module for certification.
See also
OptimalThreadLoadsAligned()

Referenced by pcl::AbstractImage::OptimalThreadRows().

◆ OptimalThreadLoadsAligned()

static Array<size_type> pcl::Thread::OptimalThreadLoadsAligned ( size_type  count,
int  align = 16,
size_type  overheadLimit = 1u,
int  maxThreads = PCL_MAX_PROCESSORS 
)
static

Returns a list of per-thread counts optimized for parallel processing of a contiguous set of items stored with a prescribed alignment.

Parameters
countNumber of processing units. A processing unit can be a single pixel, a row of pixels, or any suitable item, according to the task being performed by the caller. For optimal performance, the size in bytes of a processing unit should be even, assuming that the task will be applied to a contiguous list of count items.
alignItem alignment. The function will return a list of counts, where all counts but the last one are guaranteed to be integer multiples of this parameter. The default value is 16.
overheadLimitThread overhead limit in processing units. The function returns a list with a maximum length such that no thread would have to process less processing units than this value. The default overhead limit is one processing unit.
maxThreadsMaximum number of threads to use. The length of the returned list will be at most either this value, or the maximum number of threads currently allowed for the calling process (whichever is less), or maybe a smaller length, if necessary to enforce the specified alignment. The default value of this parameter does not impose a practical limit.

Other than the prescribed alignment, this function is equivalent to its unaligned counterpart OptimalThreadLoads().

See also
OptimalThreadLoads()

◆ Priority()

priority pcl::Thread::Priority ( ) const

Returns this thread's priority.

◆ ResetPriority()

void pcl::Thread::ResetPriority ( )
inline

Resets this thread's priority to the default value, which inherits the calling thread's priority.

Definition at line 311 of file Thread.h.

◆ Run()

virtual void pcl::Thread::Run ( )
inlinevirtual

Thread execution routine.

This member function is invoked by the PixInsight core application upon execution start, just after calling the Start() member function. During execution of this routine, it is said that this is a running thread.

Derived classes must reimplement this member function to provide specific thread functionality.

Note
There is no problem at all in calling this member function directly. This may be useful, for example, if the same code must be executed in a single thread (without calling Start()) and as multithreaded code.

Definition at line 396 of file Thread.h.

◆ SetAffinity() [1/2]

bool pcl::Thread::SetAffinity ( const Array< int > &  processors)

Sets the affinity of this thread to the specified set of processors.

Each element on the specified processors array is a zero-based index corresponding to an existing logical processor. The first processor has index zero and the last one has index n-1, where n is the total number of logical processors on the host machine. Logical processors include physical processors and processor cores, as well as logical processors on systems with hyper-threading technology.

Returns true iff the operation was performed correctly. In general, this function returns false if this thread is not running, or if the specified set contains nonexistent processor indices. It can also return false if the calling process does not have the necessary privileges, altough this should not happen under normal conditions.

Note
The CPU affinity of the calling thread cannot be changed with this function. If this thread is not running, this function returns false and does nothing.
Currently, thread affinity can only be set on Linux and Windows platforms. On FreeBSD and Mac OS X, calling this function has no effect. We hope to overcome this limitation in a future version of PCL.

◆ SetAffinity() [2/2]

bool pcl::Thread::SetAffinity ( int  processor)

Sets the CPU affinity of this thread to the specified processor.

The specified processor is a zero-based index corresponding to an existing logical processor. The first processor has index zero and the last one has index n-1, where n is the total number of logical processors on the host machine. Logical processors include physical processors and processor cores, as well as logical processors on systems with hyper-threading technology.

Returns true iff the operation was performed correctly. In general, this function returns false if this thread is not running, or if the specified processor does not exist. It can also return false if the calling process does not have the necessary privileges, altough this should not happen under normal conditions.

Note
The CPU affinity of the calling thread cannot be changed with this function. If this thread is not running, this function returns false and does nothing.
Currently, thread affinity can only be set on Linux and Windows platforms. On FreeBSD and Mac OS X, calling this function has no effect. We hope to overcome this limitation in a future version of PCL.

◆ SetPriority()

void pcl::Thread::SetPriority ( priority  )

Sets this thread's priority.

◆ SetStatus()

void pcl::Thread::SetStatus ( uint32  status)

Sets the current status of a running thread. See the documentation of Thread::Status() for more information.

Note
Calling this function for an inactive thread has no effect. The thread status can only be set for a running thread.
If the high-order bit of status is set, an abort message will be sent to the running thread. See the Abort() member function for more information.
This member function is thread-safe. It can be safely called for a running thread, even from other running threads.

◆ Sleep()

void pcl::Thread::Sleep ( unsigned  ms)

Suspends execution of this thread during the specified time interval ms in milliseconds.

◆ Start()

void pcl::Thread::Start ( priority  = ThreadPriority::Inherit,
int  processor = -1 
)

Starts thread execution with the specified scheduling priority and CPU affinity to the specified processor.

After calling this member function, the PixInsight core application will create a new execution thread from which the Run() virtual member function will be invoked for this Thread instance.

By default, the calling thread's scheduling priority is inherited by newly created threads. In general, to maximize performance in a way well adapted to the running platform, ThreadPriority::DefaultMax should be specified as the value of the priority parameter.

By default, threads have no specific CPU affinity. By specifying a valid processor index, a thread can be scheduled to run on a specific logical processor. When the specified processor is >= 0, the internal thread dispatcher will set the corresponding CPU affinity when this thread is executed, just before calling its Run() virtual member function. This is usually a more convenient way to control thread affinity than the SetAffinity() member function, because it allows setting CPU affinity before a thread starts execution.

Note
Currently, thread affinity can only be set on Linux and Windows platforms. On FreeBSD and Mac OS X, specifying a processor with this function has no effect. We hope to overcome this limitation in a future version of PCL.
Since version 1.8.0 of the PixInsight core application, nested parallelism is fully supported. This means that multiple threads can be run by calling Thread::Start() from either the root thread or any running Thread object. In versions prior to 1.8.0, a thread could only be run from the root thread.

◆ Status()

uint32 pcl::Thread::Status ( ) const

Returns the current status of this thread. The thread status is a 32-bit unsigned integer number that can be set for an active thread by calling its SetStatus() member function.

Thread status is primarily intended as an efficient mechanism to send custom messages to running threads, for thread synchronization or other control purposes.

Note
This member function is thread-safe. It can be safely called for a running thread.
This member function blocks the caller's execution until the thread status can be retrieved. Hence, the operation performed by this function is expensive in terms of thread synchronization. For a non-blocking version of this function see the documentation for TryGetStatus().

◆ TryGetStatus()

bool pcl::Thread::TryGetStatus ( uint32 status) const

Attempts to get the current status of this thread without blocking the caller's execution.

Returns true iff the thread status could be retrieved and stored in the specified status variable.

Returns false if the status couldn't be read. In this case the value of the status variable won't be changed.

Note
This member function is thread-safe. It can be safely called for a running thread.
This is a non-blocking fast version of the Status() member function. It should be used when acquiring the thread's status is not strictly necessary to continue thread execution.

◆ TryIsAborted()

bool pcl::Thread::TryIsAborted ( ) const
inline

Returns true iff this thread has been aborted, and the current thread's status could be retrieved without blocking the caller's execution.

Note
This member function is thread-safe. It can be safely called for a running thread.
This is a non-blocking fast version of the IsAborted() member function. It should be used when acquiring the thread's status is not strictly necessary to continue thread execution.

Definition at line 509 of file Thread.h.

◆ Wait() [1/2]

void pcl::Thread::Wait ( )

Suspends execution of the calling thread until this thread terminates execution. If this thread is not running, this function returns immediately.

Warning
If this thread does not return from its Run() member function, for example because this thread hangs or enters an infinite loop, the thread that calls this function will remain suspended forever (crashed).

◆ Wait() [2/2]

bool pcl::Thread::Wait ( unsigned  ms)

Suspends execution of the calling thread until one of the following conditions is met:

  • This thread terminates execution, or this thread is not running.
  • The specified time interval ms in milliseconds has elapsed.

This member function returns true if this thread has finished execution before the specified time ms in milliseconds has elapsed. It also returns true if this thread is not running.

Note
Unlike Wait(), this function cannot crash the calling thread if this thread is crashed, unless a huge amount of time is specified as the function argument.

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