next up previous contents index
Next: 3.2.3 Managing Multiple XSB Up: 3.2 Examples of Calling Previous: 3.2.1.1 An Example using   Contents   Index


3.2.2 The General XSB API

The previous section showed how to use the XSB API with both the VarString type and without, but did not consider the multi-threaded engine. In fact, there are different ways to use XSB's multi-threading that can have advantages for various situations. In the first mode, threads are managed from Prolog, with a single XSB thread called from the API; that XSB thread can then create another XSB thread that does work, and the first thread can return almost immediately to handle more requests from the API's caller. A second model allows the caller to manipulate a pool of several XSB threads, so that different XSB threads may be called from different threads over the API. In this model each C, Java, Ruby, or other thread could a number of different Prolog threads. In this section we sketch how to use the API to illustrate the first model, and sketch the second model in the next section.

Figure 3.3: Calling the Single- or Multi-Threaded Engine Using the VarString Interface
\begin{figure}\begin{small}
\begin{verbatim}...../* context.h is necessary f...
..._error_message(CTXT));xsb_close();
}\end{verbatim}
\end{small}
\end{figure}

Figure 3.3 shows how relevant portions of the previous VarString example can be adapted to use the multi-threaded engine. The main change is that a new variable is introduced on the C side that points to the context of the main thread. As pointed out in Chapter 2, each thread in the multi-threaded engine has a context in which is kept much of its thread-specific data (excluding tables and dynamic code). Of the threads running in the multi-threaded engine the thread created upon the call to xsb_init() is designated as the main thread, and is closed only upon calling xsb_close().

Within the multi-threaded engine, a call to an API function such as xsb_query_string_string() is actually a call to a specific thread to do some work (using a thread context pointer). Accordingly, since any errors produced will be specific to a given thread, all calls to error reporting functions are also thread-specific. If no specific thread is needed, it may be best just to use the main thread, which is what is done in Figure 3.3. The thread context pointer th is initialized to the main thread using the API macro xsb_get_main_thread(). Afterwards, this pointer is passed into the various interface functions by making use of XSB macros defined in context.h In the multi-threaded engine, these macros are defined as

#define CTXT th
#define CTXTc th,
while in the single-threaded engine they are defined as empty strings, as is xsb_get_main_thread(). As a result the code in Figure 3.3 will compile and run properly both for the single-threaded and the multi-threaded engines.

At this stage, suppose one wanted a new thread to execute a specific command, say do_foo. In this case, a C call such as

xsb_query_string_string(CTXTc "thread_create(do_foo,Id).",&return_string,"|")
creates a thread to execute the command, and returns the thread id of the newly created thread in return_string. The behavior of this newly created thread is exactly the same as if it were created from the XSB command line: in particular the newly created thread will automatically exit upon completion of its command. As a somewhat technical point, there are two different ways of referring to XSB threads. The foreign language interfaces described in Chapter 2 and here use pointers to thread contexts so that the interfaces use much of the same code as the XSB engine. However Prolog refers to threads using thread identifiers. The two different forms can be converted into each other by the functions xsb_thread_id_to_context() and xsb_thread_context_to_id().


next up previous contents index
Next: 3.2.3 Managing Multiple XSB Up: 3.2 Examples of Calling Previous: 3.2.1.1 An Example using   Contents   Index
Terrance Swift 2007-10-06