8.2 Monitoring threads

Normal multi-threaded applications should not need these the predicates from this section because almost any usage of these predicates is unsafe. For example checking the existence of a thread before signalling it is of no use as it may vanish between the two calls. Catching exceptions using catch/3 is the only safe way to deal with thread-existence errors.

These predicates are provided for diagnosis and monitoring tasks. See also section 8.5, describing more high-level primitives.

current_thread(?Id, ?Status)
Enumerates identifiers and status of all currently known threads. Calling current_thread/2 does not influence any thread. See also thread_join/2. For threads that have an alias-name, this name is returned in Id instead of the numerical thread identifier. Status is one of:
running
The thread is running. This is the initial status of a thread. Please note that threads waiting for something are considered running too.
false
The Goal of the thread has been completed and failed.
true
The Goal of the thread has been completed and succeeded.
exited(Term)
The Goal of the thread has been terminated using thread_exit/1 with Term as argument. If the underlying native thread has exited (using pthread_exit()) Term is unbound.
exception(Term)
The Goal of the thread has been terminated due to an uncaught exception (see throw/1 and catch/3).
thread_statistics(+Id, +Key, -Value)
Obtains statistical information on thread Id as statistics/2 does in single-threaded applications. This call returns all keys of statistics/2, although only information statistics about the stacks and CPU time yield different values for each thread.69Getting the CPU-time of a different thread is not supported on all platforms. For Microsoft, it does not work in 95/98/ME. For POSIX systems it requires times() to return values specific for the calling thread. See also section 8.2.1.
mutex_statistics
Print usage statistics on internal mutexes and mutexes associated with dynamic predicates. For each mutex two numbers are printed: the number of times the mutex was acquired and the number of collisions: the number times the calling thread has to wait for the mutex. The collision-count is not available on Windows as this would break portability to Windows-95/98/ME or significantly harm performance. Generally collision count is close to zero on single-CPU hardware.

8.2.1 Linux: linuxthreads vs. NPTL

Linux has introduces POSIX threads (pthread) using an implementation called linuxthreads, where each thread was `almost' a process. This approach has various disadvantages, such as poor performance and non-compliance with several aspects of POSIX. However, there is one advantage. Where pthread does not provide a way to get statistics per thread, we could get this info from the process-oriented times() function. Since the 2.6.x kernels, Linux by default now uses the NPTL implementation which is POSIX compliant. Unfortunately, getting per-thread CPU statistics involves reading /proc and is therefore too slow for some applications.

SWI-Prolog is setup to run with the default thread model. Unfortunately there is no way to modify this at runtime, but there is a way to select the old thread model on modern machines at link time. This is achieved using the environment variable LD_ASSUME_KERNEL which must be set to a pre-nptl kernel version for linking the main executable. The value 2.4.21 is appropriate. When building from source, this flag can be set during the build process. When using a binary distribution one could create a minimal C program and relink the system using the plld utility.