Did you know ... Search Documentation:
Pack logtalk -- logtalk-3.98.0/docs/handbook/_sources/libraries/linda.rst.txt

.. _library_linda:

linda

Linda 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:

  • Write tuples using out/1
  • Read tuples (without removing) using rd/1 and rd_noblock/1
  • Remove tuples using in/1 and in_noblock/1 The blocking operations (in/1, rd/1) suspend the process until a matching tuple becomes available. The non-blocking variants (in_noblock/1, rd_noblock/1) fail immediately if no matching tuple is found.

    Tuples are matched using standard Prolog unification, allowing patterns with variables.

API documentation

Open the `../../apis/library_index.html#linda <../../apis/library_index.html#linda>`__ link in a web browser.

Loading

To load this library, load the loader.lgt file:

::

| ?- logtalk_load(linda(loader)).

Testing

To test this library predicates, load the tester.lgt file:

::

| ?- logtalk_load(linda(tester)).

Usage

Starting a server


To start a Linda server that prints its address:

::

   | ?- linda::linda.
   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).

API Summary

Server predicates


- ``linda`` - Start server on automatic port
- ``linda(+Options)`` - Start server with options (see API
  documentation)

Client predicates
  • linda_client(+Address) - Connect to server at Host:Port
  • close_client - Close connection
  • shutdown_server - Request server shutdown
  • linda_timeout(?Old, +New) - Get/set timeout .. _tuple-operations-1:

    Tuple operations ~~~~~~~~~~~~~~~~

  • out(+Tuple) - Add tuple to space
  • in(?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)

Known issues

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.

See also