Figure 3.4 shows how two XSB threads can be
created, can receive different queries and can interleave their
backtracking and answer return. Although
Figure 3.4 demonstrated only backtracking through
simple predicates, the mechanism employed works for complicated
examples using tabling, dynamic code, and other features. All this
provides a sophisticated interface, but it is not ``fully''
multi-threaded in the following sense. When a C thread
causes XSB
to execute a command or query the thread must wait until the calling
function returns before proceeding. In certain applications it may be
useful, for example, for
to create a C thread
which runs
asynchronously from
, executing the XSB command or query and then
exiting. Alternately, an application may want to have a pool of C
threads that can interact with a pool of XSB threads.
XSB's C API has been designed to support these features. Figure 3.5 shows fragments of Figure 3.4 rewritten so that the routines to print out the answers to the queries p(X,Y,Z) and r(X,Y,Z) can be called from C threads specially designed for this purpose. More specifically, the routine query_ps() calls p_th to query p(X,Y,Z) and backtrack through its answers - its use of a single void * argument and a void * return reflect the requirements of functions that are to be called using pthread_create().
We note several points about this example. First the XSB API is a
low-level API that can be used to build application specific
interfaces, and some experience with pthread programming is useful if
multiple XSB threads are called from multiple C threads. For
instance, one issue is fairness. When called from the C API each XSB
thread
makes use of mutexes to ensure that it answers only one
query or command at a time. If multiple C threads are are waiting for
to respond to requests or queries, there is no guarantee that
the requests will be processed in any sort of order, or even that a
request will eventually be handled (In order to ensure this, the
calling program would have to use a queue or some other scheduling
mechanism to send requests to the XSB thread). In addition, it is
important to note that, the main XSB thread should only be called
from the C thread that initialized XSB.. This restriction is due
to the current design of synchronizing an XSB thread with calling
threads, and may be lifted in the future.