感谢mescalinum确认信号处理在 GNU Prolog 中默认不可用。
但是 GNU Prolog 对 C 中的用户例程有很好的支持,我已经能够编写少量 C 代码来捕获 Linux 信号并触发(如果需要)Prolog 异常(注意我的是 Ubuntu 14.04/GNU Prolog 1.3 .0 所以init_signal
函数的C 类型Bool
来自 gprolog.h - 这在 gprolog.h 1.3.1 之后发生了变化PlBool
- 请参阅1.3.0与最近的手册):
C代码“signal.c”:
#include <stdio.h>
#include <signal.h>
#include <gprolog.h>
/* signal handler */
void sig_handler(int signo)
{
if (signo == SIGHUP)
{
printf("received SIGHUP\n");
/* throw Prolog exception */
Pl_Err_Instantiation();
}
}
/* GNU Prolog goal that registers the signal handler */
/* declared with :- foreign(init_signal). */
Bool init_signal()
{
if (signal(SIGHUP, sig_handler) == SIG_ERR)
{
printf("\ncan't catch SIGHUP\n");
}
printf("%s","SIGHUP handler registered\n");
return TRUE; /* succeed */
}
Prolog“test.pl”中的测试用法——本例中的“长时间运行”查询是 o_query,用于“catch”关系,可以用 SIGHUP 中断:
:- foreign(init_signal).
:- initialization(main).
main :- write('Prolog signal test program started'),
nl,
init_signal,
catch(o_query,X,write('Prolog exception thrown')),
nl,
halt.
o_query :- repeat,
sleep(1),
fail.
编译gplc test.pl signal.c
现在,如果程序使用 ./test 运行,它可以从另一个终端中断kill -1 <test process id>
Bambam@desktop:~/prolog/signal$ ./test
Prolog signal test program started
SIGHUP handler registered
received SIGHUP
Prolog exception thrown
Bambam@desktop:~/prolog/signal$
出于我的目的,当我在 C 信号处理程序中时,我可以有效地处理传入的异常,但将其反射回 Prolog 的“抛出”(在本例中为“实例化错误”)使代码在 Prolog 中保持整洁。
我希望能够向正在执行的 GNU Prolog 进程发送(和捕获)信号的原因是因为我的系统是一个高性能并行处理 Prolog 环境,它可以触发任何长时间运行的 Prolog 进程将自己动态“拆分”成然后在其他机器上执行的多个部分。但是你基本上不能(用我的方法)预测工作的确切分布,并且在适当的时候其他处理器将被中断(即发送一个信号)以进一步分割工作量。