8.3 Thread communication

8.3.1 Message queues

Prolog threads can exchange data using dynamic predicates, database records, and other globally shared data. These provide no suitable means to wait for data or a condition as they can only be checked in an expensive polling loop. Message queues provide a means for threads to wait for data or conditions without using the CPU.

Each thread has a message-queue attached to it that is identified by the thread. Additional queues are created using message_queue_create/1.

thread_send_message(+QueueOrThreadId, +Term)
Place Term in the given queue or default queue of the indicated thread (which can even be the message queue of itself, see thread_self/1). Any term can be placed in a message queue, but note that the term is copied to the receiving thread and variable-bindings are thus lost. This call returns immediately.

If more than one thread is waiting for messages on the given queue and at least one of these is waiting with a partially instantiated Term, the waiting threads are all sent a wake-up signal, starting a rush for the available messages in the queue. This behaviour can seriously harm performance with many threads waiting on the same queue as all-but-the-winner perform a useless scan of the queue. If there is only one waiting thread or all waiting threads wait with an unbound variable an arbitrary thread is restarted to scan the queue.84See the documentation for the POSIX thread functions pthread_cond_signal() v.s. pthread_cond_broadcast() for background information.

thread_get_message(?Term)
Examines the thread message queue and if necessary blocks execution until a term that unifies to Term arrives in the queue. After a term from the queue has been unified to Term, the term is deleted from the queue.

Please note that not-unifying messages remain in the queue. After the following has been executed, thread 1 has the term b(gnu) in its queue and continues execution using A = gnat.

   <thread 1>
   thread_get_message(a(A)),

   <thread 2>
   thread_send_message(Thread_1, b(gnu)),
   thread_send_message(Thread_1, a(gnat)),

See also thread_peek_message/1.

thread_peek_message(?Term)
Examines the thread message-queue and compares the queued terms with Term until one unifies or the end of the queue has been reached. In the first case the call succeeds (possibly instantiating Term. If no term from the queue unifies this call fails.
message_queue_create(?Queue)
If Queue is an atom, create a named queue. To avoid ambiguity of thread_send_message/2, the name of a queue may not be in use as a thread-name. If Queue is unbound an anonymous queue is created and Queue is unified to its identifier.
message_queue_create(-Queue, +Options)
Create a message queue from Options. Defined options are.
alias(+Alias)
Same as message_queue_create(Alias), but according to the ISO draft on Prolog threads.
max_size(+Size)
Maximum number of terms in the queue. If this number is reached, thread_send_message/2 will suspend until the queue is drained. The option can be used if the source, sending messages to the queue, is faster than the drain, consuming the messages.