File: threads.doc

package info (click to toggle)
swi-prolog 6.6.6-1~bpo70%2B1
  • links: PTS, VCS
  • area: main
  • in suites: wheezy-backports
  • size: 82,312 kB
  • sloc: ansic: 322,250; perl: 245,822; sh: 6,651; java: 5,254; makefile: 4,423; cpp: 4,153; ruby: 1,594; yacc: 843; xml: 82; sed: 12; sql: 6
file content (1026 lines) | stat: -rw-r--r-- 44,701 bytes parent folder | download | duplicates (2)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
874
875
876
877
878
879
880
881
882
883
884
885
886
887
888
889
890
891
892
893
894
895
896
897
898
899
900
901
902
903
904
905
906
907
908
909
910
911
912
913
914
915
916
917
918
919
920
921
922
923
924
925
926
927
928
929
930
931
932
933
934
935
936
937
938
939
940
941
942
943
944
945
946
947
948
949
950
951
952
953
954
955
956
957
958
959
960
961
962
963
964
965
966
967
968
969
970
971
972
973
974
975
976
977
978
979
980
981
982
983
984
985
986
987
988
989
990
991
992
993
994
995
996
997
998
999
1000
1001
1002
1003
1004
1005
1006
1007
1008
1009
1010
1011
1012
1013
1014
1015
1016
1017
1018
1019
1020
1021
1022
1023
1024
1025
1026
\chapter{Multithreaded applications} \label{sec:threads}

SWI-Prolog multithreading is based on standard C language multithreading
support. It is not like {\em ParLog} or other parallel implementations of
the Prolog language. Prolog threads have their own stacks and only share
the Prolog \emph{heap}: predicates, records, flags and other global
non-backtrackable data.  SWI-Prolog thread support is designed with the
following goals in mind.

\begin{itemlist}
    \item[Multithreaded server applications]
Today's computing services often focus on (internet) server applications.
Such applications often have need for communication between services
and/or fast non-blocking service to multiple concurrent clients.  The
shared heap provides fast communication, and thread creation is
relatively cheap.%
    \footnote{On an Intel i7-2600K, running Ubuntu Linux 12.04,
	      SWI-Prolog 6.2 creates and joins 32,000 threads per
	      second elapsed time.}

    \item[Interactive applications]
Interactive applications often need to perform extensive computation.
If such computations are executed in a new thread, the main thread can
process events and allow the user to cancel the ongoing computation.
User interfaces can also use multiple threads, each thread dealing with
input from a distinct group of windows.  See also \secref{mt-xpce}.

    \item[Natural integration with foreign code]
Each Prolog thread runs in a native thread of the operating system,
automatically making them cooperate with \jargon{MT-safe} foreign code.
In addition, any foreign thread can create its own Prolog engine for
dealing with calling Prolog from C code.
\end{itemlist}

SWI-Prolog multithreading is based on the POSIX thread standard
\cite{Butenhof:1997:PPT} used on most popular systems except for
MS-Windows. On Windows it uses the
\url[pthread-win32]{http://sources.redhat.com/pthreads-win32/} emulation
of POSIX threads mixed with the Windows native API for smoother and
faster operation.


\section{Creating and destroying Prolog threads}
\label{sec:threadcreate}

\begin{description}
    \predicate{thread_create}{3}{:Goal, -Id, +Options}
Create a new Prolog thread (and underlying C thread) and start it
by executing \arg{Goal}.  If the thread is created successfully, the
thread identifier of the created thread is unified to \arg{Id}.
\arg{Options} is a list of options.  The currently defined options are
below.  Stack size options can also take the value \const{inf} or
\const{infinite}, which is mapped to the maximum stack size supported
by the platform.

\begin{description}
    \termitem{alias}{AliasName}
Associate an `alias name' with the thread.  This name may be used to
refer to the thread and remains valid until the thread is joined
(see thread_join/2).

    \termitem{at_exit}{:AtExit}
Register \arg{AtExit} as using thread_at_exit/1 before entering the
thread goal. Unlike calling thread_at_exit/1 as part of the normal
\arg{Goal}, this \emph{ensures} the \arg{Goal} is called. Using
thread_at_exit/1, the thread may be signalled or run out of resources
before thread_at_exit/1 is reached.

    \termitem{detached}{Bool}
If \const{false} (default), the thread can be waited for using
thread_join/2. thread_join/2 must be called on this thread to reclaim
all resources associated with the thread. If \const{true}, the system
will reclaim all associated resources automatically after the thread
finishes. Please note that thread identifiers are freed for reuse after
a detached thread finishes or a normal thread has been joined.
See also thread_join/2 and thread_detach/1.

If a detached thread dies due to failure or exception of the initial
goal, the thread prints a message using print_message/2.  If such
termination is considered normal, the code must be wrapped using
ignore/1 and/or catch/3 to ensure successful completion.

    \termitem{inherit_from}{+ThreadId}
Inherit defaults from the given \arg{ThreadId} instead of the calling
thread. This option was added to ensure that the
\const{__thread_pool_manager} (see thread_create_in_pool/4), which is
created lazily, has a predictable state. The following properties are
inherited:

    \begin{itemize}
	\item The prompt (see prompt/2)
        \item The \jargon{typein} module (see module/1)
        \item The standard streams (\const{user_input}, etc.)
        \item The default encoding (see \prologflag{encoding})
        \item The default locale (see setlocale/1)
        \item All prolog flags
	\item The limits of Prolog stacks (see set_prolog_stack/2)
    \end{itemize}

    \termitem{global}{K-Bytes}
Set the limit to which the global stack of this thread may grow.  If
omitted, the limit of the calling thread is used. See also the
\cmdlineoption{-G} command line option.

    \termitem{local}{K-Bytes}
Set the limit to which the local stack of this thread may grow.  If
omitted, the limit of the calling thread is used.  See also the
\cmdlineoption{-L} command line option.

    \termitem{c_stack}{K-Bytes}
Set the limit to which the system stack of this thread may grow.  The
default, minimum and maximum values are system-dependent.\footnote{Older
versions used \const{stack}.  This is still accepted as a synonym.}.

    \termitem{trail}{K-Bytes}
Set the limit to which the trail stack of this thread may grow.  If
omitted, the limit of the calling thread is used. See also the
\cmdlineoption{-T} command line option.
\end{description}

The \arg{Goal} argument is \emph{copied} to the new Prolog engine.
This implies that further instantiation of this term in either thread does
not have consequences for the other thread: Prolog threads do not share
data from their stacks.

    \predicate{thread_self}{1}{-Id}
Get the Prolog thread identifier of the running thread.  If the thread
has an alias, the alias name is returned.

    \predicate{thread_join}{2}{+Id, -Status}
Wait for the termination of the thread with the given \arg{Id}.  Then unify
the result status of the thread with \arg{Status}.
After this call, \arg{Id} becomes invalid and all resources associated
with the thread are reclaimed.  Note that threads with the attribute
\term{detached}{true} cannot be joined.  See also thread_property/2.

A thread that has been completed without thread_join/2 being called on
it is partly reclaimed: the Prolog stacks are released and the C thread
is destroyed. A small data structure representing the exit status of the
thread is retained until thread_join/2 is called on the thread.  Defined
values for \arg{Status} are:

\begin{description}
    \termitem{true}{}
The goal has been proven successfully.

    \termitem{false}{}
The goal has failed.

    \termitem{exception}{Term}
The thread is terminated on an exception.  See print_message/2 to turn
system exceptions into readable messages.

    \termitem{exited}{Term}
The thread is terminated on thread_exit/1 using the argument \arg{Term}.
\end{description}

    \predicate{thread_detach}{1}{+Id}
Switch thread into detached state (see \term{detached}{Bool} option at
thread_create/3) at runtime.  \arg{Id} is the identifier of the thread
placed in detached state.  This may be the result of thread_self/1.

One of the possible applications is to simplify debugging. Threads that
are created as \jargon{detached} leave no traces if they crash. For
non-detached threads the status can be inspected using
thread_property/2. Threads nobody is waiting for may be created normally
and detach themselves just before completion. This way they leave no
traces on normal completion and their reason for failure can be
inspected.

    \predicate[deprecated]{thread_exit}{1}{+Term}
Terminates the thread immediately, leaving \term{exited}{Term} as
result state for thread_join/2.  If the thread has the attribute
\term{detached}{true} it terminates, but its exit status cannot be
retrieved using thread_join/2, making the value of \arg{Term} irrelevant.
The Prolog stacks and C thread are reclaimed.

The current implementation does not guarantee proper releasing of all
mutexes and proper cleanup in setup_call_cleanup/3, etc. Please use the
exception mechanism (throw/1) to abort execution using non-standard
control.

    \predicate{thread_initialization}{1}{:Goal}
Run \arg{Goal} when thread is started.  This predicate is similar to
initialization/1, but is intended for initialization operations of
the runtime stacks, such as setting global variables as described in
\secref{gvar}.  \arg{Goal} is run on four occasions: at the call to
this predicate, after loading a saved state, on starting a new
thread and on creating a Prolog engine through the C interface. On
loading a saved state, \arg{Goal} is executed \emph{after} running the
initialization/1 hooks.

    \predicate{thread_at_exit}{1}{:Goal}
Run \arg{Goal} just before releasing the thread resources. This is to be
compared to at_halt/1, but only for the current thread. These hooks are
run regardless of why the execution of the thread has been completed.
When these hooks are run, the return code is already available through
thread_property/2 using the result of thread_self/1 as
thread identifier. Note that there are two scenarios for using exit
hooks. Using thread_at_exit/1 is typically used if the thread creates a
side-effect that must be reverted if the thread dies. Another scenario
is where the creator of the thread wants to be informed when the thread
ends. That cannot be guaranteed by means of thread_at_exit/1 because it
is possible that the thread cannot be created or dies almost instantly
due to a signal or resource error.  The \term{at_exit}{Goal} option of
thread_create/3 is designed to deal with this scenario.

    \predicate{thread_setconcurrency}{2}{-Old, +New}
\index{Solaris}%
Determine the concurrency of the process, which is defined as the
maximum number of concurrently active threads. `Active' here means they
are using CPU time. This option is provided if the thread implementation
provides pthread_setconcurrency(). Solaris is a typical example of this
family. On other systems this predicate unifies \arg{Old} to 0 (zero)
and succeeds silently.
\end{description}


\section{Monitoring threads}		\label{sec:thmonitor}

Normal multithreaded applications should not need the predicates
from this section because almost any usage of these predicates is
unsafe. For example checking the existence of a thread before signalling
it is of no use as it may vanish between the two calls. Catching
exceptions using catch/3 is the only safe way to deal with
thread-existence errors.

These predicates are provided for diagnosis and monitoring tasks. See
also \secref{thutil}, describing more high-level primitives.


\begin{description}
    \predicate{thread_property}{2}{?Id, ?Property}
True if thread \arg{Id} has \arg{Property}.  Either or both arguments
may be unbound, enumerating all relations on backtracking.
Calling thread_property/2 does not influence any thread.  See also
thread_join/2.  For threads that have an alias name, this name is
returned in \arg{Id} instead of the opaque thread identifier.
Defined properties are:

\begin{description}
	\termitem{alias}{Alias}
 \arg{Alias} is the alias name of thread \arg{Id}.
	\termitem{detached}{Boolean}
Current detached status of the thread.
	\termitem{status}{Status}
Current status of the thread.  \arg{Status} is one of:
\begin{description}
    \termitem{running}{}
The thread is running.  This is the initial status of a thread.  Please
note that threads waiting for something are considered running too.

    \termitem{false}{}
The \arg{Goal} of the thread has been completed and failed.

    \termitem{true}{}
The \arg{Goal} of the thread has been completed and succeeded.

    \termitem{exited}{Term}
The \arg{Goal} of the thread has been terminated using thread_exit/1
with \arg{Term} as argument.  If the underlying native thread has
exited (using pthread_exit()) \arg{Term} is unbound.

    \termitem{exception}{Term}
The \arg{Goal} of the thread has been terminated due to an uncaught
exception (see throw/1 and catch/3).
\end{description}
    \end{description}

See also thread_statistics/3 to obtain resource usage information and
message_queue_property/2 to get the number of queued messages for a
thread.

    \predicate{thread_statistics}{3}{+Id, +Key, -Value}
Obtains statistical information on thread \arg{Id} as statistics/2
does in single-threaded applications.  This call supports all keys
of statistics/2, although only stack sizes and CPU time yield
different values for each thread.%
	\footnote{There is no portable interface to obtain
		  thread-specific CPU time and some operating systems
		  provide no access to this information at all.  On
		  such systems the total process CPU is returned. Thread
		  CPU time is supported on MS-Windows, Linux and
		  MacOSX.}

    \predicate{mutex_statistics}{0}{}
Print usage statistics on internal mutexes and mutexes associated with
dynamic predicates. For each mutex two numbers are printed: the number
of times the mutex was acquired and the number of \jargon{collisions}:
the number of times the calling thread has to wait for the mutex.
Generally collision count is close to zero on single-CPU hardware.
\end{description}


\section{Thread communication}			\label{sec:threadcom}

\subsection{Message queues}			\label{sec:msgqueue}

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. \jargon{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/1.

\begin{description}
    \predicate{thread_send_message}{2}{+QueueOrThreadId, +Term}
Place \arg{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
\arg{Term}, the waiting threads are \emph{all} sent a wake-up 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.%
	\footnote{See the documentation for the POSIX thread functions
		  pthread_cond_signal() v.s.\ pthread_cond_broadcast()
		  for background information.}

    \predicate{thread_get_message}{1}{?Term}
Examines the thread message queue and if necessary blocks execution
until a term that unifies to \arg{Term} arrives in the queue.  After
a term from the queue has been unified to \arg{Term}, the
term is deleted from the queue.

Please note that non-unifying messages remain in the queue.  After
the following has been executed, thread 1 has the term \term{b}{gnu}
in its queue and continues execution using \arg{A}~=~\const{gnat}.

\begin{code}
   <thread 1>
   thread_get_message(a(A)),

   <thread 2>
   thread_send_message(Thread_1, b(gnu)),
   thread_send_message(Thread_1, a(gnat)),
\end{code}

See also thread_peek_message/1.

    \predicate{thread_peek_message}{1}{?Term}
Examines the thread message queue and compares the queued terms
with \arg{Term} until one unifies or the end of the queue has been
reached.  In the first case the call succeeds, possibly instantiating
\arg{Term}.  If no term from the queue unifies, this call fails.  I.e.,
thread_peek_message/1 never waits and does not remove any term from the
queue.  See also thread_get_message/3.

    \predicate{message_queue_create}{1}{?Queue}
If \arg{Queue} is an atom, create a named queue.  To avoid ambiguity
of thread_send_message/2, the name of a queue may not be in use as a
thread name.  If \arg{Queue} is unbound an anonymous queue is created
and \arg{Queue} is unified to its identifier.

    \predicate{message_queue_create}{2}{-Queue, +Options}
Create a message queue from \arg{Options}.  Defined options are:

    \begin{description}
	\termitem{alias}{+Alias}
Same as \term{message_queue_create}{Alias}, but according to the
ISO draft on Prolog threads.
	\termitem{max_size}{+Size}
Maximum number of terms in the queue.  If this number is reached,
thread_send_message/2 will suspend until the queue is drained.
The option can be used if the source, sending messages to the
queue, is faster than the drain, consuming the messages.
    \end{description}

    \predicate[det]{message_queue_destroy}{1}{+Queue}
Destroy a message queue created with message_queue_create/1. A
permission error is raised if \arg{Queue} refers to (the default queue
of) a thread. Other threads that are waiting for \arg{Queue} using
thread_get_message/2 receive an existence error.

    \predicate[det]{thread_get_message}{2}{+Queue, ?Term}
As thread_get_message/1, operating on a given queue. It is allowed (but
not advised) to get messages from the queue of other threads.  This
predicate raises an existence error exception if \arg{Queue} doesn't
exist or is destroyed using message_queue_destroy/1 while this predicate
is waiting.

    \predicate[semidet]{thread_get_message}{3}{+Queue, ?Term, +Options}
As thread_get_message/2, but providing additional \arg{Options}:

    \begin{description}
    \termitem{deadline}{+AbsTime}
The call fails (silently) if no message has arrived before
\arg{AbsTime}. See get_time/1 for the representation of absolute time.
If \arg{AbsTime} is earlier then the current time, thread_get_message/3
fails immediately. Both resolution and maximum wait time is
platform-dependent.\footnote{The implementation uses
MsgWaitForMultipleObjects() on MS-Windows and pthread_cond_timedwait()
on other systems.}

    \termitem{timeout}{+Time}
\arg{Time} is a float or integer and specifies the maximum time to wait
in seconds.  This is a relative-time version of the \const{deadline}
option.  If both options are provided, the earliest time is effective.

It \arg{Time} is 0 or 0.0, thread_get_message/3 examines the queue but
does not suspend if no matching term is available.  Note that unlike
thread_peek_message/2, a matching term is removed from the queue.

It \arg{Time} $< 0$, thread_get_message/3 fails immediately.
    \end{description}

    \predicate[semidet]{thread_peek_message}{2}{+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.

    \predicate{message_queue_property}{2}{?Queue, ?Property}
True if \arg{Property} is a property of \arg{Queue}.  Defined properties
are:

    \begin{description}
        \termitem{alias}{Alias}
Queue has the given alias name.
	\termitem{max_size}{Size}
Maximum number of terms that can be in the queue. See
message_queue_create/2.  This property is not present if there is no
limit (default).
	\termitem{size}{Size}
Queue currently contains \arg{Size} terms. Note that due to concurrent
access the returned value may be outdated before it is returned. It can
be used for debugging purposes as well as work distribution purposes.
    \end{description}

The \term{size}{Size} property is always present and may be used to
enumerate the created message queues.  Note that this predicate does
\emph{not enumerate} threads, but can be used to query the properties
of the default queue of a thread.
\end{description}

Explicit message queues are designed with the \jargon{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.

\begin{code}
%%	create_workers(?Id, +N)
%
%	Create a pool with Id and number of workers.
%	After the pool is created, post_job/1 can be used to
%	send jobs to the pool.

create_workers(Id, N) :-
	message_queue_create(Id),
	forall(between(1, N, _),
	       thread_create(do_work(Id), _, [])).

do_work(Id) :-
	repeat,
	  thread_get_message(Id, Goal),
	  (   catch(Goal, E, print_message(error, E))
	  ->  true
	  ;   print_message(error, goal_failed(Goal, worker(Id)))
	  ),
	fail.

%%	post_job(+Id, +Goal)
%
%	Post a job to be executed by one of the pool's workers.

post_job(Id, Goal) :-
	thread_send_message(Id, Goal).
\end{code}


\subsection{Signalling threads}
\label{sec:thread-signal}

These predicates provide a mechanism to make another thread execute some
goal as an \jargon{interrupt}.  Signalling threads is safe as these
interrupts are only checked at safe points in the virtual machine.
Nevertheless, signalling in multithreaded environments should be
handled with care as the receiving thread may hold a \jargon{mutex}
(see with_mutex/2).  Signalling probably only makes sense to start
debugging threads and to cancel no-longer-needed threads with throw/1,
where the receiving thread should be designed carefully to handle
exceptions at any point.

\begin{description}
    \predicate{thread_signal}{2}{+ThreadId, :Goal}
Make thread \arg{ThreadId} execute \arg{Goal} at the first
opportunity.  In the current implementation, this implies at the first
pass through the \jargon{Call port}. The predicate thread_signal/2
itself places \arg{Goal} into the signalled thread's signal queue
and returns immediately.

Signals (interrupts) do not cooperate well with the world of
multithreading, mainly because the status of mutexes cannot be
guaranteed easily.  At the call port, the Prolog virtual machine
holds no locks and therefore the asynchronous execution is safe.

\arg{Goal} can be any valid Prolog goal, including throw/1 to make
the receiving thread generate an exception, and trace/0 to start
tracing the receiving thread.

In the Windows version, the receiving thread immediately executes
the signal if it reaches a Windows GetMessage() call, which generally
happens if the thread is waiting for (user) input.
\end{description}


\subsection{Threads and dynamic predicates}	\label{sec:threadlocal}

Besides queues (\secref{msgqueue}) threads can share and exchange
data using dynamic predicates. The multithreaded version knows about
two types of dynamic predicates. By default, a predicate declared
\jargon{dynamic} (see dynamic/1) is shared by all threads. Each thread
may assert, retract and run the dynamic predicate. Synchronisation
inside Prolog guarantees the consistency of the predicate. Updates are
\jargon{logical}: visible clauses are not affected by assert/retract
after a query started on the predicate. In many cases primitives from
\secref{threadsync} should be used to ensure that application
invariants on the predicate are maintained.

Besides shared predicates, dynamic predicates can be declared with the
thread_local/1 directive. Such predicates share their attributes, but
the clause list is different in each thread.

\begin{description}
    \prefixop{thread_local}{+Functor/+Arity, \ldots}
This directive is related to the dynamic/1 directive.  It tells the
system that the predicate may be modified using assert/1, retract/1,
etc., during execution of the program.  Unlike normal shared dynamic
data, however, each thread has its own clause list for the predicate.
As a thread starts, this clause list is empty.  If there are still
clauses when the thread terminates, these are automatically reclaimed
by the system (see also volatile/1).  The thread_local property
implies the properties \jargon{dynamic} and \jargon{volatile}.

Thread-local dynamic predicates are intended for maintaining
thread-specific state or intermediate results of a computation.

It is not recommended to put clauses for a thread-local predicate into
a file, as in the example below, because the clause is only visible from the
thread that loaded the source file.  All other threads start with an
empty clause list.

\begin{code}
:- thread_local
	foo/1.

foo(gnat).
\end{code}

\textbf{DISCLAIMER} Whether or not this declaration is appropriate in
the sense of the proper mechanism to reach the goal is still debated.
If you have strong feelings in favour or against, please share them
in the SWI-Prolog mailing list.
\end{description}


\section{Thread synchronisation}		\label{sec:threadsync}

All internal Prolog operations are thread-safe. This implies that two Prolog
threads can operate on the same dynamic predicate without corrupting the
consistency of the predicate. This section deals with user-level
\jargon{mutexes} (called \jargon{monitors} in ADA or
\jargon{critical sections} by Microsoft).  A mutex is a
{\bf MUT}ual {\bf EX}clusive device, which implies that at most one thread
can \jargon{hold} a mutex.

Mutexes are used to realise related updates to the Prolog database.
With `related', we refer to the situation where a `transaction' implies
two or more changes to the Prolog database.  For example, we have a
predicate \nopredref{address}{2}, representing the address of a person
and we want to change the address by retracting the old and asserting
the new address. Between these two operations the database is invalid:
this person has either no address or two addresses, depending on the
assert/retract order.

Here is how to realise a correct update:

\begin{code}
:- initialization
	mutex_create(addressbook).

change_address(Id, Address) :-
	mutex_lock(addressbook),
	retractall(address(Id, _)),
	asserta(address(Id, Address)),
	mutex_unlock(addressbook).
\end{code}


\begin{description}
    \predicate{mutex_create}{1}{?MutexId}
Create a mutex.  If \arg{MutexId} is an atom, a \jargon{named} mutex is
created.  If it is a variable, an anonymous mutex reference is returned.
There is no limit to the number of mutexes that can be created.

    \predicate{mutex_create}{2}{-MutexId, +Options}
Create a mutex using options.  Defined options are:

    \begin{description}
	\termitem{alias}{Alias}
Set the alias name.  Using \term{mutex_create}{X, [alias(name)]}
is preferred over the equivalent \term{mutex_create}{name}.
    \end{description}

    \predicate{mutex_destroy}{1}{+MutexId}
Destroy a mutex.  After this call, \arg{MutexId} becomes invalid and
further references yield an \except{existence_error} exception.

    \predicate{with_mutex}{2}{+MutexId, :Goal}
Execute \arg{Goal} while holding \arg{MutexId}.  If \arg{Goal} leaves
choice points, these are destroyed (as in once/1).  The mutex is unlocked
regardless of whether \arg{Goal} succeeds, fails or raises an exception.
An exception thrown by \arg{Goal} is re-thrown after the mutex has been
successfully unlocked.  See also mutex_create/1 and setup_call_cleanup/3.

Although described in the thread section, this predicate is also
available in the single-threaded version, where it behaves simply as
once/1.

    \predicate{mutex_lock}{1}{+MutexId}
Lock the mutex.  Prolog mutexes are \jargon{recursive} mutexes: they
can be locked multiple times by the same thread.  Only after unlocking
it as many times as it is locked does the mutex become available for
locking by other threads. If another thread has locked the mutex the
calling thread is suspended until the mutex is unlocked.

If \arg{MutexId} is an atom, and there is no current mutex with that
name, the mutex is created automatically using mutex_create/1.  This
implies named mutexes need not be declared explicitly.

Please note that locking and unlocking mutexes should be paired
carefully. Especially make sure to unlock mutexes even if the protected
code fails or raises an exception. For most common cases, use
with_mutex/2, which provides a safer way for handling Prolog-level
mutexes.  The predicate setup_call_cleanup/3 is another way to guarantee
that the mutex is unlocked while retaining non-determinism.

    \predicate{mutex_trylock}{1}{+MutexId}
As mutex_lock/1, but if the mutex is held by another thread, this
predicates fails immediately.

    \predicate{mutex_unlock}{1}{+MutexId}
Unlock the mutex. This can only be called if the mutex is held by the
calling thread. If this is not the case, a \except{permission_error}
exception is raised.

    \predicate{mutex_unlock_all}{0}{}
Unlock all mutexes held by the current thread.  This call is especially
useful to handle thread termination using abort/0 or exceptions.  See
also thread_signal/2.

    \predicate{mutex_property}{2}{?MutexId, ?Property}
True if \arg{Property} is a property of \arg{MutexId}.  Defined properties are:

    \begin{description}
	\termitem{alias}{Alias}
Mutex has the defined alias name.  See mutex_create/2 using the `alias'
option.

	\termitem{status}{Status}
Current status of the mutex. One of \const{unlocked} if the mutex is
currently not locked, or \term{locked}{Owner, Count} if mutex is locked
\arg{Count} times by thread \arg{Owner}. Note that unless \arg{Owner}
is the calling thread, the locked status can change at any time. There
is no useful application of this property, except for diagnostic
purposes.%
	\bug{As \arg{Owner} and \arg{Count} are fetched separately from
	     the mutex, the values may be inconsistent.}
    \end{description}
\end{description}


\section{Thread support library(threadutil)}	\label{sec:thutil}

This library defines a couple of useful predicates for demonstrating and
debugging multithreaded applications. This library is certainly not
complete.

\begin{description}
    \predicate{threads}{0}{}
Lists all current threads and their status.

    \predicate{join_threads}{0}{}
Join all terminated threads. For normal applications,
dealing with terminated threads must be part of the application logic,
either detaching the thread before termination or making sure it will be
joined. The predicate join_threads/0 is intended for interactive
sessions to reclaim resources from threads that died unexpectedly
during development.

    \predicate{interactor}{0}{}
Create a new console and run the Prolog top level in this new console.
See also attach_console/0.  In the Windows version a new interactor
can also be created from the {\sf Run/New thread} menu.
\end{description}


\subsection{Debugging threads}
\label{sec:threaddebug}

Support for debugging threads is still very limited. Debug and trace
mode are flags that are local to each thread. Individual threads can be
debugged either using the graphical debugger described in
\secref{guitracer} (see tspy/1 and friends) or by attaching a console to
the thread and running the traditional command line debugger (see
attach_console/0).  When using the graphical debugger, the debugger
must be \emph{loaded} from the main thread (for example using guitracer)
before gtrace/0 can be called from a thread.


\begin{description}
    \predicate{attach_console}{0}{}
If the current thread has no console attached yet, attach one and
redirect the user streams (input, output, and error) to the new console
window. On Unix systems the console is an \program{xterm} application.
On Windows systems this requires the GUI version \program{swipl-win.exe}
rather than the console-based \program{swipl.exe}.

This predicate has a couple of useful applications.  One is to separate
(debugging) I/O of different threads.  Another is to start debugging a
thread that is running in the background.  If thread 10 is running, the
following sequence starts the tracer on this thread:

\begin{code}
?- thread_signal(10, (attach_console, trace)).
\end{code}

    \predicate{tdebug}{1}{+ThreadId}
Prepare \arg{ThreadId} for debugging using the graphical tracer.  This
implies installing the tracer hooks in the thread and switching the
thread to debug mode using debug/0.  The call is injected into the
thread using thread_signal/2.  We refer to the documentation of this
predicate for asynchronous interaction with threads.  New threads
created inherit their debug mode from the thread that created them.

    \predicate{tdebug}{0}{}
Call tdebug/1 in all running threads.

    \predicate{tnodebug}{1}{+ThreadId}
Disable debugging thread \arg{ThreadId}.

    \predicate{tnodebug}{0}{}
Disable debugging in all threads.

    \predicate{tspy}{2}{:Spec, +ThreadId}
Set a spy point as spy/1 and enable the thread for debugging using
tdebug/1.  Note that a spy point is a global flag on a predicate that
is visible from all threads.  Spy points are honoured in all threads
that are in debug mode and ignored in threads that are in nodebug
mode.

    \predicate{tspy}{1}{:Spec}
Set a spy point as spy/1 and enable debugging in all threads using
tdebug/0.  Note that removing spy points can be done using nospy/1.
Disabling spy points in	a specific thread is achieved by tnodebug/1.
\end{description}

\subsection{Profiling threads}
\label{sec:tprofile}

In the current implementation, at most one thread can be profiled at
any moment.  Any thread can call profile/1 to profile the execution
of some part of its code.  The predicate tprofile/1 allows for profiling
the execution of another thread until the user stops collecting profile
data.

\begin{description}
    \predicate{tprofile}{1}{+ThreadId}
Start collecting profile data in \arg{ThreadId} and ask the user to hit
<return> to stop the profiler.  See \secref{profile} for details on the
execution profiler.
\end{description}


\section{Multithreaded mixed C and Prolog applications}
\label{sec:foreignthread}

All foreign code linked to the multithreading version of SWI-Prolog
should be thread-safe (\jargon{reentrant}) or guarded in Prolog using
with_mutex/2 from simultaneous access from multiple Prolog threads.
If you want to write mixed multithreaded C and Prolog applications
you should first familiarise yourself with writing multithreaded
applications in C (C++).

If you are using SWI-Prolog as an embedded engine in a multithreaded
application you can access the Prolog engine from multiple threads by
creating an \jargon{engine} in each thread from which you call Prolog.
Without creating an engine, a thread can only use functions that do
\emph{not} use the \type{term_t} type (for example PL_new_atom()).

The system supports two models.  \Secref{threadoneone} describes the
original one-to-one mapping.  In this schema a native thread attaches
a Prolog thread if it needs to call Prolog and detaches it when
finished, as opposed to the model from \secref{threadmanymany}, where
threads temporarily use a Prolog engine.

\subsection{A Prolog thread for each native thread (one-to-one)}
\label{sec:threadoneone}

In the one-to-one model, the thread that called PL_initialise() has a
Prolog engine attached. If another C thread in the system wishes to call
Prolog it must first attach an engine using PL_thread_attach_engine()
and call PL_thread_destroy_engine() after all Prolog work is finished.
This model is especially suitable with long running threads that need
to do Prolog work regularly.  See \secref{threadmanymany} for the
alternative many-to-many model.

\begin{description}
    \cfunction{int}{PL_thread_self}{}
Returns the integer Prolog identifier of the engine or -1 if the calling
thread has no Prolog engine.  This function is also provided in the
single-threaded version of SWI-Prolog, where it returns -2.

    \cfunction{int}{PL_unify_thread_id}{term_t t, int i}
Unify \arg{t} with the Prolog thread identifier for thread \arg{i}.
Thread identifiers are normally returned from PL_thread_self().  Returns
-1 if the thread does not exist or the unification fails.

    \cfunction{int}{PL_thread_attach_engine}{const PL_thread_attr_t *attr}
Creates a new Prolog engine in the calling thread. If the calling thread
already has an engine the reference count of the engine is incremented.
The \arg{attr} argument can be \const{NULL} to create a thread with
default attributes.  Otherwise it is a pointer to a structure with
the definition below.  For any field with value `0', the default is
used.  The \const{cancel} field may be filled with a pointer to a
function that is called when PL_cleanup() terminates the running
Prolog engines. If this function is not present or returns \const{FALSE}
pthread_cancel() is used.  The \const{flags} field defines the following
flags:

\begin{description}
    \termitem{PL_THREAD_NO_DEBUG}{}
If this flag is present, the thread starts in normal no-debug status.
By default, the debug status is inherited from the main thread.
\end{description}

\begin{code}
typedef struct
{ unsigned long	    local_size;	   /* Stack sizes (Kbytes) */
  unsigned long	    global_size;
  unsigned long	    trail_size;
  unsigned long	    argument_size;
  char *	    alias;	   /* alias name */
  int		   (*cancel)(int thread);
  intptr_t	    flags;
} PL_thread_attr_t;
\end{code}

The structure may be destroyed after PL_thread_attach_engine() has
returned.  On success it returns the Prolog identifier for the thread
(as returned by PL_thread_self()). If an error occurs, -1 is returned.
If this Prolog is not compiled for multithreading, -2 is returned.

    \cfunction{int}{PL_thread_destroy_engine}{}
Destroy the Prolog engine in the calling thread. Only takes effect if
PL_thread_destroy_engine() is called as many times as
PL_thread_attach_engine() in this thread.  Returns \const{TRUE} on
success and \const{FALSE} if the calling thread has no engine or this
Prolog does not support threads.

Please note that construction and destruction of engines are
relatively expensive operations. Only destroy an engine if performance
is not critical and memory is a critical resource.

    \cfunction{int}{PL_thread_at_exit}{void (*function)(void *),
				       void *closure,
				       int global}
Register a handle to be called as the Prolog engine is destroyed.
The handler function is called with one \ctype{void *} argument holding
\arg{closure}. If \arg{global} is \const{TRUE}, the handler is installed
\emph{for all threads}. Globally installed handlers are executed after
the thread-local handlers. If the handler is installed local for the
current thread only (\arg{global} == \const{FALSE}) it is stored in the
same FIFO queue as used by thread_at_exit/1.
\end{description}


		 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
		 %         MANY-TO-MANY		%
		 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

\subsection{Pooling Prolog engines (many-to-many)}
\label{sec:threadmanymany}

In this model Prolog engines live as entities that are independent from
threads.  If a thread needs to call Prolog it takes one of the engines
from the pool and returns the engine when done.  This model is suitable
in the following identified cases:

\begin{itemlist}
    \item [Compatibility with the single-threaded version]
In the single-threaded version, foreign threads must serialise access to
the one and only thread engine.  Functions from this section allow
sharing one engine among multiple threads.

    \item [Many native threads with infrequent Prolog work]
Prolog threads are expensive in terms of memory and time to create and
destroy them.  For systems that use a large number of threads that only
infrequently need to call Prolog, it is better to take an engine from a pool
and return it there.

    \item [Prolog status must be handed to another thread]
This situation has been identified by Uwe Lesta when creating a .NET
interface for SWI-Prolog. .NET distributes work for an active internet
connection over a pool of threads.  If a Prolog engine contains the state
for a connection, it must be possible to detach the engine from a
thread and re-attach it to another thread handling the same connection.
\end{itemlist}

\begin{description}
    \cfunction{PL_engine_t}{PL_create_engine}{PL_thread_attr_t *attributes}
Create a new Prolog engine. \arg{attributes} is described with
PL_thread_attach_engine(). Any thread can make this call after
PL_initialise() returns success. The returned engine is not attached to
any thread and lives until PL_destroy_engine() is used on the returned
handle.

In the single-threaded version this call always returns \const{NULL},
indicating failure.

    \cfunction{int}{PL_destroy_engine}{PL_engine_t e}
Destroy the given engine.  Destroying an engine is only allowed if the
engine is not attached to any thread or attached to the calling thread.
On success this function returns \const{TRUE}, on failure the return
value is \const{FALSE}.

    \cfunction{int}{PL_set_engine}{PL_engine_t engine, PL_engine_t *old}
Make the calling thread ready to use \arg{engine}. If \arg{old} is
non-\const{NULL} the current engine associated with the calling thread
is stored at the given location. If \arg{engine} equals
\const{PL_ENGINE_MAIN} the initial engine is attached to the calling
thread. If \arg{engine} is \const{PL_ENGINE_CURRENT} the engine is not
changed. This can be used to query the current engine. This call returns
\const{PL_ENGINE_SET} if the engine was switched successfully,
\const{PL_ENGINE_INVAL} if \arg{engine} is not a valid engine handle and
\const{PL_ENGINE_INUSE} if the engine is currently in use by another
thread.

Engines can be changed at any time.  For example, it is allowed to
select an engine to initiate a Prolog goal, detach it and at a later
moment execute the goal from another thread. Note, however, that the
\ctype{term_t}, \ctype{qid_t} and \ctype{fid_t} types are interpreted
relative to the engine for which they are created. Behaviour when
passing one of these types from one engine to another is undefined.

In the single-threaded version this call only succeeds if \arg{engine}
refers to the main engine.
\end{description}


		 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
		 %		XPCE		%
		 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

\section{Multithreading and the XPCE graphics system}	\label{sec:mt-xpce}
\label{sec:xpcethread}

GUI applications written in XPCE can benefit from Prolog threads if they
need to do expensive computations that would otherwise block the UI. The
XPCE message passing system is guarded with a single \jargon{mutex},
which synchronises both access from Prolog and activation through the
GUI. In MS-Windows, GUI events are processed by the thread that created
the window in which the event occurred, whereas in Unix/X11 they are
processed by the thread that dispatches messages. In practice, the most
feasible approach to graphical Prolog implementations is to control XPCE
from a single thread and deploy other threads for (long) computations.

Traditionally, XPCE runs in the foreground (\const{main}) thread. We are
working towards a situation where XPCE can run comfortably in a separate
thread. A separate XPCE thread can be created using pce_dispatch/1. It
is also possible to create this thread as the \pllib(pce) is loaded by
setting the \prologflag{xpce_threaded} to \const{true}.

Threads other than the thread in which XPCE runs are provided with two
predicates to communicate with XPCE.

\begin{description}
    \predicate[det]{in_pce_thread}{1}{:Goal}
Assuming XPCE is running in the foreground thread, this call gives
background threads the opportunity to make calls to the XPCE thread.
A call to in_pce_thread/1 succeeds immediately, copying \arg{Goal}
to the XPCE thread.  \arg{Goal} is added to the XPCE event queue
and executed synchronous to normal user events like typing and clicking.

    \predicate[semidet]{in_pce_thread_sync}{1}{:Goal}
Same as in_pce_thread/1, but wait for \arg{Goal} to be completed.
Success depends on the success of executing \arg{Goal}. Variable
bindings inside \arg{Goal} are visible to the caller, but it should be
noted that the values are being \emph{copied}. If \arg{Goal} throws an
exception, this exception is re-thrown by in_pce_thread/1. If the
calling thread is the `pce thread', in_pce_thread_sync/1 executes a
direct meta-call. See also pce_thread/1.

Note that in_pce_thread_sync/1 is expensive because it requires copying
and thread communication.  For example, \exam{in_pce_thread_sync{true}}
runs at approximately 50,000 calls per second (AMD Phenom 9600B, Ubuntu
11.04).

    \predicate{pce_dispatch}{1}{+Options}
Create a Prolog thread with the alias name \const{pce} for XPCE
event handling. In the X11 version this call creates a thread that
executes the X11 event-dispatch loop. In MS-Windows it creates a thread
that executes a windows event-dispatch loop.  The XPCE event-handling
thread has the alias \const{pce}. \arg{Options} specifies the
thread attributes as thread_create/3.
\end{description}