The features described in this section are only enabled on Unix
systems providing POSIX threads and if the system is configured using
the --enable-mt option. SWI-Prolog multi-theading
support is very incomplete and for developers ONLY. This section however
does provide an overview of the forthcoming functionality.
SWI-Prolog multithreading is based on standard C-language
multithreading support. It is not like ParLog or other paralel
implementations of the Prolog language. Prolog threads have their own
stacks and only share the Prolog heap: predicates, records,
flags and other global non-backtrackable data. SWI-Prolog thread support
is designed with the following goals in mind.
- Multi-threaded server applications
Todays computing services often focus on (internet) server applications.
Such applications often have need for communication between services
and/or fast non-blocking service to multiple concurrent clients. The
shared heap provides fast communication and thread creation is
relatively cheap (A Pentium-II/450 can create and join approx. 10,000
threads per second on Linux 2.2).
- Interactive applications
Interactive applications often need to perform extensive computation. If
such computations are executed in a new thread, the main thread can
process events and allow the user to cancel the ongoing computation.
User interfaces can also use multiple threads, each thread dealing with
input from a distinct group of windows.
- Natural integration with foreign code
Each Prolog thread runs in a C-thread, automatically making them
cooperate with MT-safe foreign-code. In addition, any foreign
thread can create its own Prolog engine for dealing with calling Prolog
from C-code.
Below is the tentative and incomplete API for dealing with multiple
Prolog threads. Forthcoming: mutexes, semaphores,
thread-suspend and cancel, foreign-language interface and debugger
interface.
- 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 succesfully, the
thread-identifier of the created thread is unified to Id.
Options is a list of options. Currently defined options are:
- local(K-Bytes)
-
Set the limit to which the local stack of this thread may grow. If
omited, the limit of the calling thread is used. See also the
-L commandline option.
- global(K-Bytes)
-
Set the limit to which the global stack of this thread may grow. If
omited, the limit of the calling thread is used. See also the
-G commandline option.
- trail(K-Bytes)
-
Set the limit to which the trail stack of this thread may grow. If
omited, the limit of the calling thread is used. See also the
-T commandline option.
- argument(K-Bytes)
-
Set the limit to which the argument stack of this thread may grow. If
omited, the limit of the calling thread is used. See also the
-A commandline option.
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 thread do not
share data from their stacks.
- 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. Status
is one of:
- running
-
The thread is running. This is the initial status of a thread. Please
note that threats 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.
- exception(Term)
-
The Goal of the thread has been terminated due to an uncaught
exception (see throw/1
and catch/3).
- thread_join(+Id,
-Status)
-
Wait for the termination of thread with given Id. Then unify
the result-status (see thread_exit/1)
of the thread with Status. After this call, Id
becomes invalid and all resources associated with the thread are
reclaimed. See also current_thread/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 represening the
exit-status of the thread is retained until thread_join/2
is called on the thread.
- thread_exit(+Term)
-
Terminates the thread immediately, leaving
exited(Term)
as
result-state. The Prolog stacks and C-thread are reclaimed.