Codebase list swi-prolog / upstream/6.4.1 man / threads.doc
upstream/6.4.1

Tree @upstream/6.4.1 (Download .tar.gz)

threads.doc @upstream/6.4.1raw · history · blame

   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
\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{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{Unbounded thread creation}
\label{sec:mtunbound}

(SWI-)Prolog threads are rather heavyweight objects, notably on 32-bit
systems, because every thread uses a considerable amount of \emph{virtual}
address space. SWI-Prolog threads claim the stack \emph{limit} in
virtual address space for each of the runtime stacks, while on 32-bit
systems this resource is generally limited somewhere between 1~GB and
3.5~GB, depending on the operating system and operating configuration.

If SWI-Prolog starts a thread it copies the initial goal and starts a
POSIX thread which allocates a new Prolog engine that starts proving
the given goal.  If allocation of the engine fails, typically due to
lack of virtual memory space, the thread is still created with minimal
(8~Kbyte) stacks and immediately calls its exit handlers. See the option
\term{at_exit}{Goal}. Although this mechanism allows for handling this
type of error gracefully it is not safe to rely on it.  Allocating an
engine that nearly exhausts virtual address space may cause failures
in normal memory allocation that can appear anywhere in Prolog or the
foreign libraries used by it.  Such errors typically kill the process
with a fatal error.

Especially on 32-bit hardware, the design of the application must
consider this issue and avoid ungraceful termination, being conservative
with the dynamic creation of new threads.


\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.

\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);
} 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}