且构网

分享程序员开发的那些事...
且构网 - 分享程序员编程开发的那些事

带流输出的SWI-Prolog线程

更新时间:2022-06-27 01:10:23

您可以利用SWI-Prolog concurrent/3库谓词来简化代码:

You can simplify your code by taking advantage of the SWI-Prolog concurrent/3 library predicate:

另一个选择是Logtalk对高级多线程编程的支持(SWI-Prolog是它支持的后端Prolog编译器之一).

Another option is Logtalk's support for high-level multi-threading programming (SWI-Prolog is one of the backend Prolog compilers it supports).

无论如何,这是一个两步过程:首先创建目标(应并行执行),然后运行目标.但是你没有那样做. SWI-Prolog线程(默认情况下)创建为未分离.在代码中对thread_join/2谓词的调用意味着您正在等待刚创建的线程完成,然后再传递给下一个对.因此,您是正确的,并且您的代码一次运行一个线程.试试:

In any case, it's a two step process: first create the goals (that should be executed in parallel) and, second, run them. But you're not doing that. SWI-Prolog threads are created (by default) as non-detached. The call to thread_join/2 predicate in your code means that you're waiting for the thread you just created to finish before passing to the next pair. Thus, you're correct and your code is running one thread at a time. Try:

maximum(X,Y,Y) :- X =< Y,!.
maximum(X,_,X).

pair(5,6).
pair(8,7).
pair(9,9).

thread(A,B,Stream) :-
  maximum(A,B,C),
  format(Stream, "max('~w','~w',~w).~n",[A,B,C]).

start(File) :-
  open(File,append,Stream,[]),
  findall(thread(A,B,Stream), pair(A,B), Goals),
  length(Goals, N),
  concurrent(N, Goals, []),
  close(Stream).

示例执行:

?- [concurrent].
true.

?- start(results).
true.

?- 
% halt
$ cat results
max('5','6',6).
max('8','7',8).
max('9','9',9).

使用目标数作为要使用的线程数(即工作程序数)不是***选择.***使用从硬件的内核数(或每个内核可以运行的线程数)得出的N值.

Using the number of goals as the number of threads (aka workers) to use is, however, not the best choice. Likely better to use a value for N derived from the number of cores (or the number of threads each core can run) of your hardware.

Logtalk解决方案使用其threaded/1内置谓词类似(但更具可移植性)(但它采用目标并列而不是目标列表).

The Logtalk solution is similar (but more portable) using its threaded/1built-in predicate (but it takes a goal conjunction instead of a goal list).