具有流输出的SWI-Prolog线程

时间:2014-11-10 17:22:13

标签: multithreading prolog swi-prolog

如果我有一个类似下面的程序,prolog是否会尝试同时证明maximum/3三次?即每个线程都有自己的核心(假设在计算机上可用)?

我的实际程序在这里maximum/3的位置运行一个谓词大约需要2个小时,我需要计算70个等价的pair/2。这种方法有用吗?如果不是为什么不呢?我已经设置了程序运行但是从输出看来它一次只做一个线程。

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]),
  thread_exit(C).


start(File) :-
  open(File,append,Stream,[]),
   forall(
      pair(A,B),
      (
       thread_create(thread(A,B,Stream),Id,[]),
       thread_join(Id,exited(X)),
       writeln(X)
      )
     ),
  close(Stream).

1 个答案:

答案 0 :(得分:3)

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

http://www.swi-prolog.org/pldoc/doc_for?object=thread:concurrent/3

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

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

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

然而,使用目标数作为线程数(也称为工作者)不是最佳选择。最好使用从{0}的核心数量(或每个核心可以运行的线程数)得到的N值。

Logtalk解决方案使用其threaded/1内置谓词类似(但更具可移植性)(但它需要一个目标连接而不是目标列表)。