Linda is a concept for process communication.
For an introduction and a deeper description, see [Carreiro & Gelernter 89a] or [Carreiro & Gelernter 89b], respectively.
One process is running as a server and one or more processes are running as clients. The processes are communicating with sockets and supports networks.
The server is in principle a blackboard on which the clients can write
(out/1
), read (rd/1
) and remove (in/1
) data. If the
data is not present on the blackboard, the predicates suspend the process
until they are available.
There are some more predicates besides the basic out/1
, rd/1
and in/1
. The in_noblock/1
and rd_noblock/1
does not
suspend if the data is not available--they fail instead. A blocking fetch
of a conjunction of data can be done with in/2
or
rd/2
.
Example: A simple producer-consumer. In client 1:
producer :- produce(X), out(p(X)), producer. produce(X) :- .....
In client 2:
consumer :- in(p(A)), consume(A), consumer. consume(A) :- .....
Example: Synchronization
..., in(ready), %Waits here until someone does out(ready) ...,
Example: A critical region
..., in(region_free), % wait for region to be free critical_part, out(region_free), % let next one in ...,
Example: Reading global data
..., rd(data(Data)), ..., or, without blocking: ..., rd_noblock(data(Data)) -> do_something(Data) ; write('Data not available!'),nl ), ...,
Example: Waiting for one of several events
..., in([e(1),e(2),...,e(n)], E), % Here is E instantiated to the first tuple that became available ...,
The server is the process running the "blackboard process". It is an ordinary SICStus process which can be run on a separate machine if necessary.
To load the package, enter the query
| ?- use_module(library('linda/server')).
and start the server with linda/0
or linda/1
.
linda
linda(+Hook)
| ?- linda((Host:Port)-(my_module:mypred(Host,Port))).will call
mypred/2
in module my_module
when the server is
started. mypred/2
could start the client-processes, save the
address for the clients etc. Note that the module must be present in
Goal.
The clients are one or more sicstus processes which have connection(s) to the server.
To load the package, enter the query
| ?- use_module(library('linda/client')).
Some of the following predicates fail if they don't receive an answer
from the Linda-server in a reasonable amount of time. That time is set
with the predicate linda_timeout/2
.
linda_client(+Address)
linda/0
and linda/1
.
It is not possible to be connected to two Linda-servers in the same time.
This predicate can fail due to a timeout.
close_client
linda_timeout(?OldTime, ?NewTime)
off
or of the form Seconds:Milliseconds. The former
value indicates that the timeout mechanism is disabled, that is, eternal
waiting. The latter form is the timeout-time.
out(+Tuple)
in(?Tuple)
out/1
).
in_noblock(?Tuple)
in(+TupleList, ?Tuple)
in/1
but succeeds when either of the tuples in TupleList
is available. Tuple is unified with the fetched tuple. If that
unification fails, the tuple is not reinserted in the tuple-space.
rd(?Tuple)
in/1
: the tuple is not removed.
rd_noblock(?Tuple)
rd(+TupleList, ?Tuple)
in/2
but does not remove any tuples.
bagof_rd_noblock(?Template, +Tuple, ?Bag)
bagof/3
. The variables could be existentially quantified with
^/2
as in bagof/3
.
The operation is performed as an atomic operation.
This predicate can fail due to a timeout.
Example:
Assume that only one client is connected to the server and that the tuple-space
initially is empty.
| ?- out(x(a,3)), out(x(a,4)), out(x(b,3)), out(x(c,3)). yes | ?- bagof_rd_noblock(C-N, x(C,N), L). C = _32, L = [a-3,a-4,b-3,c-3], N = _52 ? yes | ?- bagof_rd_noblock(C, N^x(C,N), L). C = _32, L = [a,a,b,c], N = _48 ? yes