WSTPServer 的介绍
WSTPServer 是一个服务器程序,可以为新收到的 WSTP(Wolfram 符号传输协议)连接启动和维护 Wolfram 语言内核. 该程序侦听单个 WSTP 终端,允许任何数量的客户端连接到已知位置以获取内核.
该程序将所有流量发送到其管理的内核,并允许 WSTPServer 的链接如同直接链接到内核一样表现. 内核可通过内核池的使用配置特定属性. 由于 WSTPServer 内核可以先连接,再断开连接,到再连接,所以你可以维护一个可以从不同程序或机器连接到的长期时域. 简单来说,你可以把 WSTPServer 想成是一个预启动、预配置的 Wolfram 语言内核,代替传统的在需要的时候启动一个新内核的流程.
WSTPServer 是一个服务器程序,它必须处于运行状态,才能与其相连接.
$ /Applications/Mathematica.app/Contents/SystemFiles/Links/WSTPServer/wstpserver
WSTPServer: Logger (0, 2020-09-29 16:50:00): Information:
Using "/Applications/Mathematica.app/Contents/MacOS/WolframKernel" as a default kernel path
WSTPServer: Logger (0, 2020-09-29 16:50:05): Information:
Listening for new connections on port 31415
...
$ "C:\Program Files\Wolfram Research\Mathematica\12.2\SystemFiles\Links\WSTPServer\wstpserver.exe"
WSTPServer: Logger (0, 2020-09-29 16:50:00): Information:
Using "C:\Program Files\Wolfram Research\Mathematica\12.2\wolfram.exe" as a default kernel path
WSTPServer: Logger (0, 2020-09-29 16:50:05): Information:
Listening for new connections on port 31415
...
在 Linux 系统中,在终端中运行以下内容可启动 WSTPServer:
$ /usr/local/Wolfram/Mathematica/12.2/SystemFiles/Links/WSTPServer/wstpserver
WSTPServer: Logger (0, 2020-09-29 16:50:00): Information:
Using "/usr/local/Wolfram/Mathematica/12.2/Executables/WolframKernel" as a default kernel path
WSTPServer: Logger (0, 2020-09-29 16:50:05): Information:
Listening for new connections on port 31415
...
关于上述内容,记住只有 12.2 或之后版本的 Wolfram 语言的设计包含了 wstpserver. 如果你的产品不是 Mathematica,则根据自己产品的情况调整上述路径(如,产品为 Wolfram 桌面).
Wolfram 语言内核通常被其与用户的连接所限制:当连接断开时,相关内核也会断开,同时其正在做的所有工作也会停止. 然而,WSTPServer 允许用户在不停止其工作的情况下与内核断开连接,并在之后重新连接到同一个内核.
通过 WSTPServer 连接到内核的其中一个好处是,你可以建立状态(比如,通过加载文件、定义和计算表达式的方式),然后让内核处于活跃状态,这样以后即使是再不同的机器上,你也可以重新连接到内核. 在 "桥接到之前使用过的内核" 章节中会给出范例.
另一个优势是,WSTPServer 可以在受干扰的网络连接状况下阻止内核死机,允许内核继续工作. 网络连接可能很不稳定,有时也无法维护. 为了回到断开连接的内核,用户所需要做的就是重新连接到 WSTPServer 并将其指向连接已经连接丢失的内核.
最后一个范例是关于长时间运算. 用户可以从由在 WSTPServer 管理的内核中进行长时间运算开始,然后当计算预计要完成时,获取结果. 在初始内核忙碌时,用户还可以连接到由 WSTPServer 管理的其他内核并给它们提供任务.
术语 "桥梁" 会在本文档中进场用到. WSTPServer 就像一个中间人,在客户端和内核之间来回通信. 桥梁就是 WSTPServer 在客户端和内核之间建立的连接. "断开桥接" 即断开客户端和内核之间的连接,然后客户端可桥接到另一个内核.
内核池是共享用户配置属性,如初始化代码,的一组内核. 大多数由 WSTPServer 管理的内核都是这种池子的成员,且至少有一个内核池子必须设置为默认池. 提供给默认池中的内核的连接不要求特定内核或池. 配置多个内核池允许你对不同的用途目的有不同的预初始化内核.
想要了解更多关于默认池和内核池的配制过程的信息,请参见“配置文件”章节. 想要了解更多关于连接到特定内核的信息,请参见 Wolfram 语言函数 WSTPServer`ConnectKernel 和 WSTP 命令 ConnectKernel 的描述. 在“桥接到特别配制池”的章节中给出了一个范例,描述如何使用 WSTPServer`ConnectKernel 桥接到特定内核池.
本章节详细描述了如何将 WSTPServer 与多个常用组件一起使用.
与 WolframScript 一起使用
WolframScript 是 Wolfram 语言的一个命令行脚本编译器,可以运行 Wolfram 语言代码、函数和已部署 API. WolframScript 还能连接到 WSTPServer 并与其内核交互.
$ wolframscript -wstpserver -code "StringReverse[\"hello\"]"
olleh
WolframScript 允许快速再连接到 WSTPServer 内核. 为了安全达到这个目标,推荐在用户必须管理的文件系统的 profiles 中追溯特定内核的连接情况. WolframScript 在用户参数文件中记录正在使用的内核的 ID,使其可以被重新连接.
在没有 WSTPServer 的情况下使用 WolframScript 时,在每次计算时你都会得到一个新的内核. 使用设置了 -startprofile 和 -continueprofile 的 WSTPServer 让你可以在多个 WolframScript 计算中使用相同的内核维护会话.
程序页面 "WolframScript" 的 "DETAILS" 会话更详细地描述了用户参数文件和 -wstpserver、-startprofile 和 -continueprofile 这些选项. 会话 "OPTIONS" 提供了一个有用的 WolframScript's 命令行选项的高级概览.
与笔记本界面一起使用
下列说明描述了如何将笔记本前端连接到 WSTPServer 和如何与其内核进行交互:
4. 选择高级选项的开关. 在名称为 "MLOpen 的参数" 的文本框中,输入下列内容,其中 "port" 和 "host",(可选)应被 WSTPServer 实际监听的端口和主机替代:
并行计算中的使用
WSTPServer 可以管理一个并行内核的池子,供并行计算功能使用. 并行计算功能需要额外配置,这样才可以连接到 WSTPServer 并行内核. 章节“使用并行计算功能”中给出了一个范例,描述了在前端中使用该功能的过程.
在 WSTP C 语言绑定中的使用
从你自己的 WSTP 项目中很容易连接到 WSTPServer. WSTP 连接到 WSTPServer 与连接到普通内核的方式几乎一样. 通常来说,WSTPServer 会在客户端连接的时候给客户端发送一些 InputNamePacket. WSTPServer 然后会向内核发送客户端的通信,并向客户端发送内核的通信. 从客户端的角度,似乎是直接链接到内核.
上述描述的一个例外是,WSTPServer 允许将一个命令类别发送给 WSCommandPacket 数据包中的 WSTP 连接. 这些命令被 WSTPServer 拦截并没有发送给内核. 这些命令的描述在章节 "命令语言" 中给出.
下列抽样程序连接到 WSTPServer 并进行运算. 除了打开链接的方式外,这是一个完全标准的 WSTP 程序. 注意调用到 WSOpenString 的 "-linkmode connect -linkname 31415 -linkprotocol TCPIP -linkoptions 4" 规格.
/************************************
include directives
*************************************/
#include "stdio.h" /* printf */
#include "wstp.h" /* WSENV, WSLINK, WSInitialize, WSOpenArgcArgv, ... */
/************************************
define directives
*************************************/
#define WSTP_ENVIRONMENT_ERROR 1
#define WSTP_OPEN_ERROR 2
#define WSTP_ACTIVATION_ERROR 3
#define WSTP_INPUTNAMEPACKET_ERROR 4
#define WSTP_GENERAL_ERROR 5
/************************************
connecting to a link server
*************************************/
/* entry point */
int main(int argc, char **argv)
{
WSENV env;
WSLINK link;
int error;
/* initialize a WSTP environment */
env = WSInitialize(NULL);
if(env == NULL)
{
(void) printf("%s\n", "Could not initialize a WSTP environment");
return WSTP_ENVIRONMENT_ERROR;
}
/* open a link to a WSTPServer listening on port 31415 on the local machine */
link = WSOpenString(env, "-linkmode connect -linkname 31415 -linkprotocol TCPIP -linkoptions 4", &error);
if(link == NULL || error)
{
(void) printf("%s\n", "Could not open a link to WSTPServer");
return WSTP_OPEN_ERROR;
}
/* activate the link to WSTPServer */
error = WSActivate(link);
if(!error)
{
(void) printf("%s\n", "Could not activate the link to WSTPServer");
return WSTP_ACTIVATION_ERROR;
}
/* receive InputNamePacket packet */
if(WSNextPacket(link) != INPUTNAMEPKT)
{
(void) printf("%s\n", "Could not receive InputNamePacket packet");
return WSTP_INPUTNAMEPACKET_ERROR;
}
(void) WSNewPacket(link);
/* send over the link:
EvaluatePacket[2 + 2] */
if(
!(
WSPutFunction(link, "EvaluatePacket", 1) &&
WSPutFunction(link, "Plus", 2) &&
WSPutInteger(link, 2) &&
WSPutInteger(link, 2) &&
WSFlush(link)
)
)
{
(void) printf("%s\n", "General WSTP error occurred");
return WSTP_GENERAL_ERROR;
}
/* read off packets until ReturnPacket */
while(
(WSNextPacket(link) != RETURNPKT) &&
(WSError(link) == WSEOK)
) { }
if(WSError(link) != WSEOK)
{
(void) printf("%s\n", "General WSTP error occurred");
return WSTP_GENERAL_ERROR;
}
/* clean up */
(void) WSClose(link);
(void) WSDeinitialize(env);
return 0;
}
首先在当前工作目录中搜索配置文件. 若不存在有效的配置文件,则会在应用数据目录中创建一个有默认内容的配置文件.
{
# Lines that begin with # are comments
# "AllowStealingKernels":false,
# "AllowSilentKernelReplacement":false,
# "EnableAutomaticKernelConnection":false,
# "SendInputNamePacketUponKernelConnection":true,
"Pools":
{
"KernelPoolOne":
{
# "Default":true,
# Only uncomment one of the "KernelPath" lines below
# Make sure to change the value to reflect the actual location of your Wolfram kernel binary
# "KernelPath":"C:\\Program Files\\Wolfram Research\\Mathematica\\13.2\\wolfram",
# "KernelPath":"/usr/local/Wolfram/Mathematica/13.2/Executables/WolframKernel",
# "KernelPath":"/Applications/Mathematica.app/Contents/MacOS/WolframKernel",
# "InitializationCode":"x=2+2",
# "InitializationFile":"/path/to/your/initialization/file.wl",
# "KernelOptions":"-yourkerneloption1 -yourkerneloption2",
# "KeepAlive":true,
# "MinimumKernelNumber":2,
# "ParallelKernels":false,
# "ReservePreviouslyConnectedKernels":false
},
# "KernelPoolTwo":
# {
# "ParallelKernelDefault":true,
# "ParallelKernels":true,
# Only uncomment one of the "KernelPath" lines below
# Make sure to change the value to reflect the actual location of your Wolfram kernel binary
# "KernelPath":"C:\\Program Files\\Wolfram Research\\Mathematica\\13.2\\wolfram",
# "KernelPath":"/usr/local/Wolfram/Mathematica/13.2/Executables/WolframKernel",
# "KernelPath":"/Applications/Mathematica.app/Contents/MacOS/WolframKernel"
# }
}
}
键-值数据对
WSTPServer 可识别下列在配置文件中的根密钥:
AllowStealingKernels |
true
| 客户端是否可以用内核 ID 桥接到一个已桥接到另一个客户端的内核 | |
AllowSilentKernelReplacement |
false
| 当桥接内核死机,应在不关闭客户端链接的情况下静静地用一个新内核替换这个死机内核 | |
EnableAutomaticKernelConnection |
false
| 默认池的内核是否应在连接完成后立即与客户端进行桥接,这与只在第一个非 WSCommandPacket 表达式发送给客户端链接时桥接内核的操作不同 | |
Pools | required | 要使用的 WSTPServer 的池子列表 | |
SendInputNamePacketUponKernelConnection |
true
| 是否应为在客户端连接后发生的桥接事件发送 InputNamePacket |
将 AllowSilentKernelReplacement 设置为 true,则(例如,由于 KeepAlive 标志变量设为 false 而导致的) WSTPServer 自己关闭的内核不会被替换. 若 AllowSilentKernelReplacement 为 false,则当桥接内核死机时,桥接到该内核的客户端链接会被关闭.
如果 EnableAutomaticKernelConnection 为 true,内核将在建立后立即与客户端链接进行桥接. 这可以减少使用客户端链接进行第一次运算所需的时间,因为内核在需要之前已经准备就绪.
Default | automatic | 是否将这个池子作为新客户端的默认池 | |
InitializationCode | "" | 池子中为内核运行的初始化代码 | |
InitializationFile |
""
| 池子中为内核运行的初始化文件 | |
KernelPath | automatic | 池子中的内核会运行的可执行 Wolfram 语言内核的路径 | |
KernelOptions | "" | 池子中的内核会运行的可执行 Wolfram 语言其他命令行选项 | |
KeepAlive |
true
| 是否无限期保持内核活跃,或在断开桥接时关闭内核 | |
MaximumKernelNumber | automatic | 池子可以包含的最大数量的运行内核 | |
MinimumKernelNumber |
2
| 池子会一直保持的最小数量的运行内核 | |
ParallelKernelDefault | automatic | 是否将该池子用作并行运算的默认池 | |
ParallelKernels |
false
| 池子的内核是否应为并行运算配置 | |
ReservePreviouslyConnectedKernels | true | 是否之前已经桥接的内核仅在通过内核 ID 请求的情况下才能再次桥接 |
WSTPServer 会预启动数量等于在 MinimumKernelNumber 启动时的值的内核. 这些内核可通过配置文件键 InitializationCode 或 InitializationFile 进行预热.
将 KeepAlive 设定为 true,在客户端断开连接时内核不会关闭,并允许其被同一客户端或不同客户端重新连接. 客户端在使用 Wolfram 语言函数 WSTPServer`DisconnectKernel 或 WSTP 命令 DisconnectKernel 而非 Quit 或 Exit 时必须小心,这个操作可能会导致内核退出.
可通过命令的使用对 WSTPServer 进行动态控制. 命令直接通过 WSTP 连接直接发送到在一个称为 WSCommandPacket 的特殊封装器中的 WSTPServer ;这些命令的结果则发回到 ReturnPacket 数据包. WSCommandPacket 功能存在的目的是给程序员编写自己的 WSTP 程序与 WSTPServer 一起使用. WSCommandPacket 的范例参见章节 "Use with the在 WSTP C 语言绑定中的使用".
CloseKernel | 关闭指定内核 | |
ConnectKernel | 用指定内核桥接当前连接 | |
ConnectParallelKernel | 用在并行内核默认池中第一个可用的内核桥接当前连接 | |
DisconnectKernel | 断开当前与其桥接内核的连接 | |
GetKernelBusyStatus | 告知桥接到当前连接的内核是否忙于计算 | |
GetKernelID | 获取桥接到当前连接的内核的 ID | |
GetNumberOfAvailableParallelKernels | 获取并行内核默认池中可用内核的数量 | |
GetPoolName | 获取桥接到当前连接的内核池的名称 | |
GetServerInformation | 获取所有池和所有内核的信息 | |
SetAllowSilentKernelReplacement | 设置是否允许或禁止内核死机时在不通知的情况下替换桥接到当前连接的内核 | |
SetKeepAlive | 设置在当前连接断开或桥接结束时是否关闭桥接到当前连接的内核 | |
SetReserveKernel | 设置当断开桥接时,当前内核是否仅可以桥接到通过 ID 请求的客户端 | |
StartKernel | (在任何池子之外)启动一个内核,并返回其 ID |
以下子章节详细描述了所有上面给出的 WSTP 命令.
WSTP 命令: CloseKernel
一旦成功,则返回 ReturnPacket["{\"status\":\"ExecutionSuccess\"}"];若失败了,则返回 ReturnPacket["{\"status\":\"ExecutionError\"}"].
WSTP 命令: ConnectKernel
若 kernelSpecifier 是内核 ID,则 WSCommandPacket[ConnectKernel["kernelSpecifier"]] 用 ID 为 kernelSpecifier 的内核桥接当前连接,若 kernelSpecifier 是内核池名称,则用名称为 kernelSpecifier 的内核池中的可用内核桥接. 若 kernelSpecifier 是内核 ID,则会中止任何用指定内核进行的现存桥接. 若内核忙于之前桥接客户端的计算,则该函数会在等待一个短暂的默认超时时间后失败.
若 kernelSpecifier 是内核 ID,则 WSCommandPacket[ConnectKernel["kernelSpecifier", timeout]] 用 ID 为 kernelSpecifier 的内核桥接当前连接,若 kernelSpecifier 是内核池名称,则会使用名称为 kernelSpecifier 的内核池中可用内核进行桥接. 若 kernelSpecifier 是内核 ID,则中指任何用指定内核进行的现存桥接. 若内核忙于之前桥接客户端的计算,则该函数会在等待 timeout 秒后失败.
若成功,则返回 ReturnPacket["{\"status\":\"ExecutionSuccess\"}"] ;若失败,则返回 ReturnPacket["{\"status\":\"ExecutionError\"}"].
WSTP 命令: ConnectParallelKernel
WSCommandPacket[ConnectParallelKernel[]]用并行内核默认池中的可用内核桥接当前连接. 若内核依然忙于之前桥接的客户端的计算,则该函数会在等待一个短暂的默认超时时间后失败.
WSCommandPacket[ConnectParallelKernel[timeout]] 用并行内核默认池中的可用内核桥接当前连接. 若内核依然忙于之前桥接的客户端的计算,则该函数会在等待 timeout 秒之后失败.
若成功,则返回 ReturnPacket["{\"status\":\"ExecutionSuccess\"}"];若失败,则返回 ReturnPacket["{\"status\":\"ExecutionError\"}"].
WSTP 命令: DisconnectKernel
若成功,则返回 ReturnPacket["{\"status\":\"ExecutionSuccess\"}"];若失败,则返回 ReturnPacket["{\"status\":\"ExecutionError\"}"] .
WSTP 命令: GetKernelBusyStatus
若成功,则返回 ReturnPacket["{\"result\":\"True\"}"] 或 ReturnPacket["{\"result\":\"False\"}"];若失败,则返回 ReturnPacket["{\"status\":\"ExecutionError\"}"] .
WSTP 命令: GetKernelID
若成功,则返回 ReturnPacket["{\"result\":\"id\"}"] ;若失败,则返回 ReturnPacket["{\"status\":\"ExecutionError\"}"] .
WSTP 命令:GetNumberOfAvailableParallelKernels
若成功,则返回 ReturnPacket["{\"result\":\"num\"}"] ;若失败,则返回 ReturnPacket["{\"status\":\"ExecutionError\"}"] . num 的值是并行内核默认池中可用内核的数量.
WSTP 命令:GetPoolName
若成功,则返回 ReturnPacket["{\"result\":\"name\"}"] ;若失败,则返回 ReturnPacket["{\"status\":\"ExecutionError\"}"] .
WSTP 命令:GetServerInformation
若成功,则返回 ReturnPacket["json"] ;若失败,则返回 ReturnPacket["{\"status\":\"ExecutionError\"}"]. 若成功,则 json 会匹配下面给出的 JSON 架构::
{
"result":
{
# An object containing configured pools and their properties
"Pools":
{
string: # The name of a particular pool
# An object containing the properties of a particular pool and their values
{
"InitializationCode":string,
"InitializationFile":string,
"MaximumKernelNumber":number,
"MinimumKernelNumber":number,
"KeepAlive":Boolean,
"EntryPool":Boolean,
"KernelPath":string,
"PreferFreshKernel":Boolean,
"ReservePreviouslyConnectedKernels":Boolean,
"ParallelKernels":Boolean,
"ParallelKernelEntryPool":Boolean
},
...
}
}
}
}
WSTP 命令:SetAllowSilentKernelReplacement
WSCommandPacket[SetAllowSilentKernelReplacement[setting]] 允许或禁止在内核死机时在不通知的情况下重启桥接到当前连接的内核. setting 的值应为 True 或 False.
若当前连接未桥接,则 SetAllowSilentKernelReplacement 失败. SetAllowSilentKernelReplacement 覆写 AllowSilentKernelReplacement 的关于当前桥接的配置文件键.
若成功,则返回 ReturnPacket["{\"status\":\"ExecutionSuccess\"}"] ;若失败,则返回 ReturnPacket["{\"status\":\"ExecutionError\"}"].
WSTP 命令:SetKeepAlive
WSCommandPacket[SetKeepAlive[setting]] 在当前连接断开或桥接结束时指导 WSTPServer 是否关闭桥接到当前连接的内核. setting 的值应为 True 或 False.
若成功,则返回 ReturnPacket["{\"status\":\"ExecutionSuccess\"}"] ;若失败,则返回 ReturnPacket["{\"status\":\"ExecutionError\"}"] .
WSTP 命令:SetReserveKernel
WSCommandPacket[SetReserveKernel[setting]] 设置在断开桥接时当前内核是否仅可通过请求 ID 的方式桥接到客户端. setting 的值应为 True 或 False.
若当前连接未被桥接,或内核并非池子的一部分,则 SetReserveKernel 失败. SetReserveKernel 对内核的效果在整个桥接事件过程中一直持续. SetReserveKernel 覆写 ReservePreviouslyConnectedKernels 关于桥接的配置文件键.
若成功,则返回 ReturnPacket["{\"status\":\"ExecutionSuccess\"}"];若失败,则返回 ReturnPacket["{\"status\":\"ExecutionError\"}"].
WSTP 命令:StartKernel
若成功,则返回 ReturnPacket["{\"result\":\"id\"}"];若失败,则返回 ReturnPacket["{\"status\":\"ExecutionError\"}"] .
WSTPServer`CloseKernel | 关闭指定内核 | |
WSTPServer`ConnectKernel | 用指定内核桥接当前连接 | |
WSTPServer`DisconnectKernel | 断开当前连接与其桥接内核的桥接 | |
WSTPServer`GetKernelID | 获取桥接到当前连接的内核的 ID | |
WSTPServer`GetPoolName | 获取桥接到当前连接的内核所在池的名称 | |
WSTPServer`GetServerInformation | 获取所有池子和内核的信息 | |
WSTPServer`SetAllowSilentKernelReplacement | 设置是否在内核死机时在不通知的情况下允许或禁止替换内核 | |
WSTPServer`SetKeepAlive | 设置在当前连接断开或桥接结束时是否关闭桥接到当前连接的内核 | |
WSTPServer`SetReserveKernel | 设置在断开桥接时当前内核是否尽可通过客户端以 ID 请求的方式进行桥接 | |
WSTPServer`StartKernel | (在任意池子之外)启动一个内核,并返回其 ID |
Wolfram 语言函数:WSTPServer`CloseKernel
Wolfram 语言函数:WSTPServer`ConnectKernel
若 kernelSpecifier 是内核 ID,则 WSTPServer`ConnectKernel["kernelSpecifier"] 用 ID 为 kernelSpecifier 的内核桥接当前连接,若 kernelSpecifier 是池子名称,则用属于名称为 kernelSpecifier 的池子中的可用内核来桥接当前连接. 若 kernelSpecifier 为内核 ID,则中止任何与指定内核相关的现存桥接. 若内核依然忙于之前桥接客户端的计算,则函数会等待一个短暂地默认超时时间然后失败.
若 kernelSpecifier 是内核 ID,则 WSTPServer`ConnectKernel["kernelSpecifier", timeout] 用 ID 为 kernelSpecifier 的内核桥接当前连接,若 kernelSpecifier 是池子名称,则用属于名称为 kernelSpecifier 的池子中的可用内核来桥接当前连接. 若 kernelSpecifier 为内核 ID,则中止任何与指定内核相关的现存桥接. 若内核依然忙于之前桥接客户端的计算,则函数会等待 timeout 秒后失败.
Wolfram 语言函数:WSTPServer`DisconnectKernel
Wolfram 语言函数:WSTPServer`GetKernelID
Wolfram 语言函数:WSTPServer`GetPoolName
Wolfram 语言函数:WSTPServer`GetServerInformation
Wolfram 语言函数:WSTPServer`SetAllowSilentKernelReplacement
若内核死机,WSTPServer`SetAllowSilentKernelReplacement[setting] 可允许或禁止在不通知的情况下重启桥接到当前连接的内核. setting 的值应为 True 或 False.
若当前连接没有被桥接,则 WSTPServer`SetAllowSilentKernelReplacement 失败. WSTPServer`SetAllowSilentKernelReplacement 覆写 AllowSilentKernelReplacement 与当前桥接相关的配置文件键.
Wolfram 语言函数:WSTPServer`SetKeepAlive
如果当前连接未被桥接,或内核不是池子的一部分,则WSTPServer`SetKeepAlive 失败. WSTPServer`SetKeepAlive 对内核的效果在整个桥接事件中一直持续. WSTPServer`SetKeepAlive 覆写 KeepAlive 关于桥接的配置文件键.
Wolfram 语言函数:WSTPServer`SetReserveKernel
若当前连接未被桥接,或若桥接到当前连接的内核并非池子的一部分,则 WSTPServer`SetReserveKernel 失败. WSTPServer`SetReserveKernel 对内核的效果会在未来桥接事件中一直持续. WSTPServer`SetReserveKernel 覆写内核的配置文件中的 ReservePreviouslyConnectedKernels 键.
Wolfram 语言函数:WSTPServer`StartKernel
WSTPServer 的命令行选项如下:
-h, --help | 打印帮助文本 | |
-l, --log-level n | 指定信息的冗长水平 | |
-f, --log-file [file] |
给指定文件撰写信息
| |
-a, --advertise [service] |
若出现,则将链接服务器通知为指定服务
| |
-p, --port port | 监听指定端口 | |
-i, --interface interface | 监听指定界面 | |
-c, --configuration-file file | 使用指定配置文件 |
error, 1 | 报告服务器启动/关机错误并打印成功启动的信息 | |
debug, 2 | 报告第一层的所有内容和所有排除故障信息 | |
trace, 3 | 报告第二层的所有内容和所有已处理 WSTP 流量 |
若使用了
--advertise [service]
或 -a [service]
,则 WSTPServer 会尝试将将自身通知为 WSTPServer-Instance
或 WSTPServer-Instance-service
,取决于 service 是否被指定. WSTPServer 会记录其通知对象的服务名称.利用并行计算功能
WSTPServer 可以通过 Wolfram 语言并行计算功能管理一个并行内核池.
以下说明展示了如何通过使用前端的 WSTPServer 利用并行计算功能:
# wstpserver.conf: place in the current working directory
{
"Pools":
{
"IProvideParallelKernels":
{
"Parallel":true,
"MinimumKernelNumber":4
}
}
}
3. 用 AppendToConfiguredKernels["port@hostname", num] 将 WSTPServer 并行内核添加到并行计算功能. 第一个参数描述的是 WSTPServer 连接到的端口和主机名称(可选). 第二个参数描述的是要使用的 WSTPServer 并行内核的数量.
桥接到特别配置池
WSTPServer 允许因特别原因配置池子(比如:通过使用共享初始化文件). 在不是默认池子的情况下,会要求通过命令语言来使用这样的池子. 可以使用 Wolfram 语言函数 WSTPServer`ConnectKernel 和 WSTP 命令 ConnectKernel 来桥接到池子.
下列说明演示了如何使用 WolframScript 桥接到特别配置的池子:
# wstpserver.conf: place in the current working directory
{
"Pools":
{
"IDefineX":
{
"InitializationCode":"x=4"
}
}
}
2. 使用控制台,运行 wolframscript -wstpserver -startprofile. 若不能发现 WSTPServer,则使用 -wstpserver wstpserverbase 选项.
3. 在 WolframScript REPL 中,使用 WSTPServer`GetPoolName[] 选择性地验证当前被桥接的内核所在的池子. 注意在给定池子初始化代码的情况下,x 和预期一样计算为 4.
$ wolframscript -wstpserver -kernelpool AlternativeThree
In[1]:= WSTPServer`GetPoolName[]
Out[1]= IDefineX
In[2]:= x
Out[2]= 4
In[3]:=
桥接到之前使用过的内核
在建立好状态后,返回到之前使用过的内核是很有用的. 通常情况下,这会要求使用配置文件键 KeepAlive 将 WSTPServer 配置为永久保持活跃状态. 也会需要 Wolfram 语言函数 WSTPServer`ConnectKernel 或 WSTP 命令 ConnectKernel.
下列说明展示了如何在内核中建立状态,然后使用 WolframScript 返回到该内核:
# wstpserver.conf: place in the current working directory
{
"Pools":
{
"IBuildUpState":
{
"KeepAlive":true
}
}
}
2. 使用控制台,运行 wolframscript -wstpserver -startprofile. 若不能发现 WSTPServer,则使用 -wstpserver wstpserverbase 选项.
$ wolframscript -wstpserver -startprofile
In[1]:= WSTPServer`GetKernelID[]
Out[1]= a806-2645-9651
In[2]:=
In[10]:= WSTPServer`DisconnectKernel[]
$
7. 使用 WSTPServer`GetKernelID[] 有选择性地验证当前被桥接的内核的 ID.
$ wolframscript -wstpserver -continueprofile
In[11]:= WSTPServer`GetKernelID[]
Out[11]= a806-2645-9651
In[12]:=
使用 WolframScript 配置文件系统
WolframScript 允许快速重新连接到 WSTPServer 内核. 推荐在用户必须管理的配置文件中追溯到对特定内核的连接. WolframScript 在配置文件中记录正在使用的内核的 ID,以便允许重新连接到该内核.
程序页面 "WolframScript" 中的 "详细信息" 章节详细描述了配置文件系统,以及 -wstpserver, -startprofile 和 -continueprofile 这些选项. 章节 "选项" 提供了一个有用的高阶 WolframScript 命令行选项概览.
下列说明展示了如何使用 WolframScript 桥接到有特定属性的内核:
# wstpserver.conf: place in the current working directory
{
"Pools":
{
"IHaveSpecificProperties":
{
"KeepAlive":true,
"ReservePreviouslyConnectedKernels":false
}
}
}
2. 创建一个包含指定属性的 WSTPServer 内核.
# sampleprofile
KEEPALIVE=TRUE # I want a kernel with "KeepAlive" set to true
RESERVE=TRUE # I want a kernel with "ReservePreviouslyConnectedKernels" set to false
3. 使用控制台,运行 wolframscript -wstpserver -startprofile sampleprofile. 若不能发现 WSTPServer,则使用 -wstpserver wstpserverbase 选项.
$ wolframscript -wstpserver -startprofile sampleprofile
In[1]:=
4. 在 WolframScript REPL 中,下定义并建立状态.
In[1]:= x = 2 + 2
Out[1]:= 4
In[10]:= WSTPServer`DisconnectKernel[]
$
$ wolframscript -wstpserver -continueprofile sampleprofile
In[11]:= x
Out[11]:= 4
在与和配置相反的 WSTPServer 断开连接后保持内核活跃
通常情况下,在与 WSTPServer 断开连接后想要保持内核活跃则需要 WSTPServer 配置为将配置文件键 KeepAlive 设置为 true,但 Wolfram 语言函数 WSTPServer`SetKeepAlive 和 WSTP 命令 SetKeepAlive 可以永久保持当前桥接的内核活跃.
1. 使用 WSTPServer 内核配置 创建笔记本.
2. 在笔记本内部,使用 WSTPServer`GetKernelID[] 获取当前内核 ID 的 ID. 结果是很重要的:会让您可以在以后返回到当前内核.
4. 通过 wolframscript -wstpserver -continueprofile 返回到该内核. 若不能发现 WSTPServer,则使用 -wstpserver port@host 选项.
$ wolframscript -wstpserver -continueprofile
In[11]:= WSTPServer`GetKernelID[]
Out[11]= 825c-6cbd-129b
In[12]:=
保留一个有重要工作的内核
在断开桥接的情况下,仅允许通过客户端请求 ID 的方式才能桥接到客户端的功能是很重要的. 这会使得该内核仅供指定需要的用户使用,且这会让不需要这个指定内核的用户无法访问该内核对话. 若配置文件键 ReservePreviouslyConnectedKernels 设置为 true 则上述为默认行为.
Wolfram 语言函数 WSTPServer`SetReserveKernel 或 WSTP 命令 SetReserveKernel 允许在无论 ReservePreviouslyConnectedKernels 的值是多少的情况下都保留当前内核. 下列说明演示了如何使用 WSTPServer`SetReserveKernel 和前端成功保留并安全与内核断开桥接:
1. 使用 WSTPServer 内核配置创建笔记本.
2. 在笔记本内部,保留有 WSTPServer`SetReserveKernel[True] 的内核.
监控 WSTPServer
WSTPServer 是一个服务器程序,所以检查其当前状态并获取诊断信息会很有用. 为此提供了 Wolfram 语言函数 WSTPServer`GetServerInformation 或 WSTP 命令 GetServerInformation 的功能.
下列说明展示了如何使用前端获取 WSTPServer 的当前状态:
1. 使用 WSTPServer 内核配置 创建笔记本.