| Did you know ... | Search Documentation: |
| Pack logtalk -- logtalk-3.99.0/docs/handbook/_sources/libraries/linda.rst.txt |
.. _library_linda:
lindaLinda is a classic coordination model for process communication. This library provides a Linda tuple-space implementation. Requires both multi-threading and sockets support. It supports SWI-Prolog, Trealla Prolog, and XVM.
The tuple-space is a shared blackboard where processes can:
out/1-2 predicatesrd/1-2 and
rd_noblock/1-2 predicatesin/1-2 and in_noblock/1-2
predicates
The blocking predicates (in/1-2, rd/1-2) suspend the process
until a matching tuple becomes available. The non-blocking variants
(in_noblock/1-2, rd_noblock/1-2) fail immediately if no matching
tuple is found. There are also additional predicates for list
operations. Tuples are matched using unification.
Open the `../../apis/library_index.html#linda <../../apis/library_index.html#linda>`__ link in a web browser.
To load this library, load the loader.lgt file:
::
| ?- logtalk_load(linda(loader)).
To test this library predicates, load the tester.lgt file:
::
| ?- logtalk_load(linda(tester)).
The main library entities are the linda_server and linda_client
categories. These categories provide a clean separation between server
and client code. For backward compatibility with the previous version of
this library, a linda object importing both categories is also
provided. The usage examples that follow use this object. An object
importing the linda_server category must use the threaded/0
directive.
Starting a server
To start a Linda server that prints its address:
::
| ?- linda::linda.
% Server started at localhost:54321
...
To start a server with a callback when it starts:
::
| ?- linda::linda([(Host:Port)-format('Server at ~w:~w~n', [Host, Port])]).
The server runs until all clients disconnect after a shutdown request.
Connecting a client
~~~~~~~~~~~~~~~~~~~
To connect to a server:
::
| ?- linda::linda_client(localhost:54321).
Tuple operations
~~~~~~~~~~~~~~~~
Write a tuple:
::
| ?- linda::out(message(hello, world)).
Read a tuple (blocking):
::
| ?- linda::rd(message(X, Y)).
X = hello,
Y = world
Remove a tuple (blocking):
::
| ?- linda::in(message(X, Y)).
X = hello,
Y = world
Non-blocking operations:
::
| ?- linda::rd_noblock(message(X, Y)).
no % if no matching tuple exists
| ?- linda::in_noblock(message(X, Y)).
no % if no matching tuple exists
Wait for one of several tuples:
::
| ?- linda::in([task(1, X), task(2, X), done], Tuple).
Alternative syntax using ``in_list/2``:
::
| ?- linda::in_list([task(1, X), task(2, X), done], Tuple).
Similarly for reading:
::
| ?- linda::rd_list([status(ready), status(waiting)], Status).
Collect all matching tuples atomically (read without removing):
::
| ?- linda::findall_rd_noblock(N, counter(N), Counters).
Collect and remove all matching tuples atomically:
::
| ?- linda::findall_in_noblock(X, item(X), Items).
Disconnecting
~~~~~~~~~~~~~
Close the client connection:
::
| ?- linda::close_client.
Request server shutdown (server stops accepting new connections):
::
| ?- linda::shutdown_server, linda::close_client.
Timeout control
~~~~~~~~~~~~~~~
Set a timeout for blocking operations:
::
| ?- linda::linda_timeout(Old, 5:0). % 5 seconds timeout
Disable timeout (wait forever):
::
| ?- linda::linda_timeout(_, off).
Examples
--------
Producer-Consumer
Producer (client 1):
::
producer :-
produce(X),
linda::out(item(X)),
producer.
Consumer (client 2):
::
consumer :-
linda::in(item(X)),
consume(X),
consumer.
Critical Region
::
critical_section :-
linda::in(mutex), % acquire lock
do_critical_work,
linda::out(mutex). % release lock
Initialize the mutex:
::
| ?- linda::out(mutex).
Synchronization
Wait for a signal:
::
| ?- linda::in(ready). % blocks until someone does out(ready)
Send a signal:
::
| ?- linda::out(ready).
Server predicates
- ``linda`` - Start server on automatic port - ``linda(Options)`` - Start server with options Client predicates
linda_client(Address) - Connect to server at Host:Portclose_client - Close connectionshutdown_server - Request server shutdownlinda_timeout(Old, New) - Get/set timeout
Tuple predicates (single/default server)
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~out(Tuple) - Add tuple to spacein(Tuple) - Remove matching tuple (blocking)in_noblock(Tuple) - Remove matching tuple (non-blocking)in(TupleList, Tuple) - Remove one of several tuples (blocking)in_list(TupleList, Tuple) - Remove one of several tuples
(blocking)rd(Tuple) - Read matching tuple (blocking)rd_noblock(Tuple) - Read matching tuple (non-blocking)rd(TupleList, Tuple) - Read one of several tuples (blocking)rd_list(TupleList, Tuple) - Read one of several tuples (blocking)findall_rd_noblock(Template, Tuple, List) - Collect all matching
tuples (atomic read)findall_in_noblock(Template, Tuple, List) - Collect and remove all
matching tuples (atomic remove)
Tuple predicates (multiple servers) ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Variants of the predicates above with an additional first argument for
the server address or the server alias (an atom; default is
blackboard).
Recent versions of macOS seem to disable the mapping of localhost to
127.0.0.1. This issue may prevent some functionality from working.
This can be fixed either by editing the /etc/hosts file or by using
'127.0.0.1' as the host argument instead of localhost.