【问题标题】:SWI-Prolog threads with stream output具有流输出的 SWI-Prolog 线程
【发布时间】:2014-11-11 03:19:39
【问题描述】:

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

我的实际程序需要大约 2 小时来在 maximum/3 的位置运行一个谓词,我需要计算 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).

【问题讨论】:

    标签: multithreading prolog swi-prolog


    【解决方案1】:

    您可以利用 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).
    

    但是,使用目标数作为要使用的线程数(也称为工作线程数)并不是最佳选择。可能最好使用从硬件的内核数(或每个内核可以运行的线程数)得出的 N 值。

    Logtalk 解决方案与使用其threaded/1built-in 谓词类似(但更便携)(但它使用目标连词而不是目标列表)。

    【讨论】:

    • 非常感谢 :)
    猜你喜欢
    • 1970-01-01
    • 2014-06-10
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-01-01
    • 1970-01-01
    相关资源
    最近更新 更多