## 8.1 Creating and destroying Prolog threads

thread_create(:Goal, -Id, +Options)
  Create a new Prolog thread (and underlying C-thread) and start it by executing Goal. If the thread is created successfully, the thread-identifier of the created thread is unified to Id. 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.
  local(K-Bytes)
    Set the limit to which the local stack of this thread may grow. If omitted, the limit of the calling thread is used. See also the -L command-line option.
  global(K-Bytes)
    Set the limit to which the global stack of this thread may grow. If omitted, the limit of the calling thread is used. See also the -G command-line option.
  trail(K-Bytes)
    Set the limit to which the trail stack of this thread may grow. If omitted, the limit of the calling thread is used. See also the -T command-line option.
  argument(K-Bytes)
    Set the limit to which the argument stack of this thread may grow. If omitted, the limit of the calling thread is used. See also the -A command-line option.
  stack(K-Bytes)
    Set the limit to which the system stack of this thread may grow. The default, minimum and maximum values are system-dependant.
  alias(AliasName)
    Associate an `alias-name' with the thread. This named may be used to refer to the thread and remains valid until the thread is joined (see thread_join/2).
  detached(Bool)
    If `false` (default), the thread can be waited for using thread_join/2. thread_join/2 must be called on this thread to reclaim the all resources associated to 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.

  The Goal argument is copied to the new Prolog engine. This implies 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.

thread_self(-Id)
  Get the Prolog thread identifier of the running thread. If the thread has an alias, the alias-name is returned.
thread_join(+Id, -Status)
  Wait for the termination of thread with given Id. Then unify the result-status of the thread with Status. After this call, Id becomes invalid and all resources associated with the thread are reclaimed. Note that threads with the attribute `detached(true)` cannot be joined. See also thread_property/2.

  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:

  true
    The goal has been proven successfully.
  false
    The goal has failed.
  exception(Term)
    The thread is terminated on an exception. See print_message/2 to turn system exceptions into readable messages.
  exited(Term)
    The thread is terminated on thread_exit/1 using the argument Term.
thread_detach(+Id)
  Switch thread into detached-state (see `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 PL_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 not-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.

thread_exit(+Term)
  Terminates the thread immediately, leaving `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.
thread_initialization(:Goal)
  Run Goal when thread is started. This predicate must be compared with initialization/1, but is intended for initialization operations of the runtime stacks, such as setting global variables as described in section 6.3. Goal is run on four occasions: at the call to this predicate, after loading a saved state, on starting a new thread and on creating a Prolog engine through the C interface. On loading a saved state, Goal is executed after running the initialization/1 hooks.
thread_at_exit(:Goal)
  Run Goal just before releasing the thread resources. This is to be compared to at_halt/1, but only for the current thread. These hooks are ran regardless of why the execution of the thread has been completed. As these hooks are run, the return-code is already available through thread_property/2 using the result of thread_self/1 as thread-identifier.
thread_setconcurrency(-Old, +New)
  Determine the concurrency of the process, which is defined as the maximum number of concurrently active threads. `Active' here means they are using CPU time. This option is provided if the thread-implementation provides pthread_setconcurrency(). Solaris is a typical example of this family. On other systems this predicate unifies Old to 0 (zero) and succeeds silently.