
concurrent(+MaxThreads, +Goals, +Options)

   Execute goals concurrently, using multiple threads

Arguments
   MaxThreads          A positive integer
   Goals               A list of callable terms
   Options             A list of option terms

Type
   library(concurrency)

Description

    Execute the goals in Goals concurrently/in parallel.  Succeed once all
    goals have succeeded.  Only the first solution for each goal is computed.
    Fail (or throw) as soon as one of the goals is found to fail (or throw).
    
    Operationally, a copy of each goal is executed in an engine.  Once all
    goals have succeeded, all goals are simultaneously instantiated to their
    first solutions.  The equivalent sequential operation could be written as:
    
    concurrent(1, Goals, _) :-
	( foreach(Goal,Goals), foreach(Copy,Copies) do
	    copy_term(Goal, Copy),
	    once(Copy)
	),
	Goals = Copies.
    
    A maximum of MaxThreads engines is used to work in parallel.  If there
    are more goals than engines, engines are reused as they become available.
    Use get_flag(cpu_count,N) to obtain the number of processors on the
    machine, which might be a good value for MaxThreads.  If some goals are
    expected to fail, a higher number of threads can be advantageous for
    finding failures earlier.
    
    The Options argument can be used to pass extra options for the creation
    of the worker engines.  In particular, the stack size options local(KBytes)
    and global(KBytes) can be used to limit their memory consumption.
    
    Due to the overheads of engine creation and destruction, this predicate
    is only useful for sufficiently long-running goals.
    

Modes and Determinism
   concurrent(+, +, +) is semidet

Modules
   This predicate is sensitive to its module context (tool predicate, see @/2).

See Also
   concurrent_or / 3, engine_create / 2
