Concurrency

Synchronization: with_mutex/2, mutex_create/1, thread_local predicates, message_queue_create/1, thread_signal/2, thread_pool_create/3.

39.1 Threads (SWI-Prolog)

Synchronization: with_mutex/2, mutex_create/1, thread_local predicates, message_queue_create/1, thread_signal/2, thread_pool_create/3.

?- thread_create(worker(1), Id, []), thread_join(Id, Status).

worker(N) :- thread_self(Me), format("worker ~w in thread ~w~n", [N, Me]).

% Message queues
?- thread_self(Me),
   thread_create((thread_get_message(ping(From)), thread_send_message(From, pong)), T, []),
   thread_send_message(T, ping(Me)),
   thread_get_message(pong).

% Parallel map
?- concurrent_maplist([X, Y]>>(Y is X * X), [1, 2, 3, 4], L).
?- concurrent(4, [G1, G2, G3], []).        % run goals with 4 workers
?- first_solution(X, [solve_a(X), solve_b(X)], []).   % race strategies
?- concurrent_forall(member(X, Items), process(X)).

39.2 Engines (SWI)

Engines are coroutines that run a goal and yield answers on demand:

Use for generators, agents, lazy evaluation, and stateful aggregation.

?- engine_create(X, member(X, [a, b, c]), E),
   engine_next(E, A1), engine_next(E, A2).    % A1 = a, A2 = b
?- engine_create(S, sum_loop(0, S), E), engine_post(E, 5, R).   % send data in

39.3 Global variables

b_setval(counter, 0), b_getval(counter, V).    % backtrackable
nb_setval(total, 0), nb_getval(total, V).      % non-backtrackable

39.4 Delimited continuations

Basis for effect-handler-style programming (iterators, DCG-like state threading, tabling implementation in SWI).

reset(Goal, Ball, Cont)    % run Goal until it calls shift(Ball)
shift(Ball)