![]() |
YAP 7.1.0
|
Prolog threads can exchange data using dynamic predicates, database records, and other globally shared data. More...
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/2
class message_queue_create/1 |
message_queue_create(? Queue)
If Queue is an atom, create a named queue To avoid ambiguity on 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
class message_queue_destroy/1 |
message_queue_destroy(+ Queue)
Destroy a message queue created with message_queue_create/1 It is not allows to destroy the queue of a thread Neither is it allowed to destroy a queue other threads are waiting for or, for anonymous message queues, may try to wait for later
class thread_send_message/1 |
thread_send_message(+ Term)
Places Term in the message-queue of the thread running the goal 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
class thread_send_message/2 |
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 wakeup 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
class thread_get_message/1 |
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 unified to Term, the term is deleted from the queue and this predicate returns
Please note that not-unifying messages remain in the queue After the following has been executed, thread 1 has the term gnu
in its queue and continues execution using A is gnat
See also thread_peek_message/1
class thread_get_message/2 |
thread_get_message(+ Queue, ? Term)
As thread_get_message/1 , operating on a given queue It is allowed to peek into another thread's message queue, an operation that can be used to check whether a thread has swallowed a message sent to it
class 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
class thread_peek_message/2 |
thread_peek_message(+ Queue, ? Term)
As thread_peek_message/1 , operating on a given queue It is allowed to peek into another thread's message queue, an operation that can be used to check whether a thread has swallowed a message sent to it
Explicit message queues are designed with the worker-pool model in mind, where multiple threads wait on a single queue and pick up the first goal to execute Below is a simple implementation where the workers execute arbitrary Prolog goals Note that this example provides no means to tell when all work is done This must be realised using additional synchronisation