如果我有一个类似下面的程序,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).
答案 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
内置谓词类似(但更具可移植性)(但它需要一个目标连接而不是目标列表)。