Did you know ... | Search Documentation: |
Creating and destroying Prolog threads |
thread_create(Goal, Id, [])
. See thread_create/3.
Id is the alias name if the option alias(name)
is given. Otherwise it is a blob of type thread
.
The anonymous blobs are subject to atom garbage collection. If a thread
handle is garbage collected and the thread is not detached, it
is joined if it has already terminated (see thread_join/2)
and detached otherwise (see thread_detach/1).198Up
to version 7.3.23, anonymous thread handles were integers. Using
integers did not allow for safe checking of the thread's status as the
thread may have died and the handle may have been reused and did not
allow for garbage collection to take care of forgotten threads.
The thread identifier blobs are printed as <thread>(
I,Ptr)
,
where I is the internal thread identifier and Ptr
is the unique address of the identifier. The I is accepted as
input argument for all thread APIs that accept a thread identifier for
convenient interaction from the toplevel. See also thread_property/2.
Options is a list of options. The currently defined
options are below. Stack size options can also take the value inf
or
infinite
, which is mapped to the maximum stack size
supported by the platform.
domain_error
is raised. Referring to CPUs equal to or
higher than the known number of CPUs returns an existence_error
.
This option is currently implemented for systems that provide pthread_attr_setaffinity_np(). The option is silently ignored on other systems.bugThere is currently no way to discover whether this option is supported.
false
(default
true
), the new thread is created with the property
debug(false)
and debugging is disabled before the new
thread is started. The thread debugging predicates such as tspy/1
and tdebug/0
do not signal threads with the debug property set to
false
.199Currently,
the flag is only used as a hint for the various debugging primitives,
i.e., the system does not really enforce that the target thread stays in nodebug
mode.false
(default), the thread can be waited for using
thread_join/2. thread_join/2
must be called on this thread to reclaim all resources associated with
the thread. If true
, the system will reclaim all associated
resources automatically after the thread finishes. Please note that
thread identifiers are freed for reuse after a detached thread finishes
or a normal thread has been joined. See also thread_join/2
and thread_detach/1.
If a detached thread dies due to failure or exception of the initial goal, the thread prints a message using print_message/2. If such termination is considered normal, the code must be wrapped using ignore/1 and/or catch/3 to ensure successful completion.
__thread_pool_manager
(see thread_create_in_pool/4),
which is created lazily, has a predictable state. The following
properties are inherited:
user_input
, etc.).current_input
and current_output
are bound
to user_input
and user_output
.max_size(o)
ption for details.inherit_from(ThreadId)
.The Goal argument is copied to the new Prolog engine. This implies that further instantiation of this term in either thread does not have consequences for the other thread: Prolog threads do not share data from their stacks.
error(thread_error(Id, Status)
, _)
is raised,
where
Status is the status as returned by thread_join/2.detached(true)
option for thread_create/3
and thread_detach/1).
A thread that has been completed without thread_join/2 being called on it is partly reclaimed: the Prolog stacks are released and the C thread is destroyed. A small data structure representing the exit status of the thread is retained until thread_join/2 is called on the thread. Defined values for Status are:
Note that the pthread primitive pthread_join() cannot be interrupted. Some systems provide pthread_timedjoin_np(). If this is provided thread_join/2 is implemented as a loop of timed joins with a 0.25 sec timeout while signals are being tested after each timeout. Such systems allow combining thread_join/2 with call_with_time_limit/2 as well as signalling threads blocked in thread_join/2 using thread_signal/2.
detached(Bool)
option at
thread_create/3)
at runtime. Id is the identifier of the thread placed in
detached state. This may be the result of thread_self/1.
One of the possible applications is to simplify debugging. Threads that are created as detached leave no traces if they crash. For non-detached threads the status can be inspected using thread_property/2. Threads nobody is waiting for may be created normally and detach themselves just before completion. This way they leave no traces on normal completion and their reason for failure can be inspected.
exited(Term)
as
result state for thread_join/2.
If the thread has the attribute
detached(true)
it terminates, but its exit status cannot be
retrieved using thread_join/2,
making the value of Term irrelevant. The Prolog stacks and C
thread are reclaimed.
The current implementation is based on the reserved
unwind(
exception. This
implies that, unlike the previous implementation that was based on the C
pthread_exit() function, the implementation is safe from the
Prolog point of view. However, it is limited by the semantics of the
unwind exceptions. See section
4.10.1 for details.
thread_exit(Term)
)
This predicate raises a permission_error
if it is known
that the thread cannot handle this case.
at_exit(Goal)
option of
thread_create/3
is designed to deal with this scenario.
The Goal is executed with signal processing disabled. This
avoids that e.g., thread_signal(Thread, abort)
kills the
exit handler rather than the thread in the case the body of Thread
has just finished when the signal arrives.
affinity(+Affinity)
of thread_create/3.
This predicate is only present if this functionality can be supported and has been ported to the target operating system. Currently, only Linux support is provided.