mfp吧 关注:779贴子:4,972
  • 1回复贴,共1

可编程科学计算器1.8.0.79发布了,请到酷安网下载

只看楼主收藏回复

在这个最新版本中,可编程科学计算器进一步完善了并行计算的功能,修正了一系列的bug。现在用户可以在任意一台支持MFP语言的设备上(该设备运行基于JAVA的可编程科学计算器,基于安卓的可编程科学计算器,或者可编程科学计算器编译生成的安卓应用),发送一段代码给另外一台支持MFP语言的设备执行。第二台设备同样行基于JAVA的可编程科学计算器,基于安卓的可编程科学计算器,或者可编程科学计算器编译生成的安卓应用,注意第一台和第二台设备完全可以运行基于不同的平台的可编程科学计算器,或者一台运行可编程科学计算器,另一台运行可编程科学计算器编译生成的安卓应用,或者两台均运行可编程科学计算器编译生成的安卓应用。但需要注意的是两台设备的可编程科学计算器版本均必须为1.8.0.79或以上,如果运行的是可编程科学计算器编译生成的安卓应用,该安卓应用必须由可编程科学计算器1.8.0.79或以上版本编译生成。另外,在当前,下层通信协议仅仅支持TCPIP。
MFP语言实现并行计算是通过call ... endcall语句。call和endcall语句定义了MFP语言call程序块的边界。call程序块是一段不在本进程中而是在别的进程中执行的指令。call语句是call程序块的开始。在call语句中,call关键字后面紧跟着连接对象,然后是on关键字,最后是一串call程序块的参数变量。call程序块的参数变量都是在call语句之前就已经声明的普通的变量。每一个参数变量都只能被一个call语句所使用。endcall语句标志着call程序块的中止。endcall语句有一个可选参数。该参数是call程序块在本地进程的返回变量。返回变量也是在call程序块之前声明的普通变量。返回变量只能被一个call程序块所使用而且不能同时作为call程序块的参数变量。
我们可以把一个call语句看作是一个函数的开始。与普通函数不同的是,call程序块并非是在本地进程中运行,而是在另外一个进程中运行。运行call程序块的进程可以是本机,也可以是另外一台设备。运行call程序块的进程通过call语句中的连接对象和本地进程连接。运行call程序块的进程可以看到call程序块参数变量的值的变化,也可以修改call程序块参数变量的值。call程序块对自己的参数变量的值的修改会反应到本地进程。但是需要注意的是,MFP语言并不保证本地进程和call程序块进程对程序块参数变量的值的修改会被实时同步到对方,也不保证按修改的顺序进行同步传递。MFP语言唯一保证的是在一个进程内对一个call程序块参数变量的修改是原子性的,也就是只有上一次修改完成了之后,对值的新的修改,不管是来自客户端还是服务器端,才能开始。需要注意的是这个原子性只是应用于一个进程。由于call程序块进程和本地进程都有一份程序块参数变量的拷贝,对于一个程序块参数变量的两份拷贝在不同的进程中同时进行修改不违背修改的原子性。当call程序块遇到endcall语句或者return语句时停止运行并返回。如果return语句返回一个值,位于本地进程的endcall语句将收到返回值并将返回值赋给call程序块在本地进程的返回变量(如果endcall语句声明了返回变量的话)。
需要注意的是,不同于call程序块的参数变量,call程序块的返回变量采用的是阻塞模式。换句话说,当call程序块被发送到远端执行后,任何在本地进程读取call程序块的返回变量的值的语句都将被阻塞,直到call程序块返回(不管有没有返回值)为止。
以下是call程序块的一个例子:
variable local_interface, remote_interface, ret
local_interface = ::mfp::paracomp::connect::generate_interface("TCPIP", "192.168.1.101")//客户端(本地进程)地址
ret = ::mfp::paracomp::connect::initialize_local(local_interface, false)
print("initialize_local ret = " + ret + "\n")
remote_interface = ::mfp::paracomp::connect::generate_interface("TCPIP", "192.168.1.107")//服务器端(运行call程序块的进程)地址
ret = ::mfp::paracomp::connect::connect(local_interface, remote_interface)//从客户端连接到服务器端
print("connect ret = " + ret + "\n")
//connect函数的返回值是一个基于数组的字典,"CONNECT"关键字所对应的就是连接对象的定义。如果connect函数失败,"CONNECT"关键字对应的值为NULL。
variable conn = ::mfp::data_struct::array_based::get_value_from_abdict(ret, "CONNECT")
variable a = "hekko, 48", b = 3+7i, c=["LCH"]
call conn on a, b
a = 88
b = "KIL"
print("Hello ....\n")
return 54
endcall c
//我们必须先取回c的值。c的值能够取回方才意味着call程序块已经返回。
print("c = " + c)
//当c的值取回之后,我们可以打印出a和b的值。可以看到这时a和b的值已经发生了更改。如果我们在print("c = " + c)语句之前打印a和b的值,
//我们可能无法观察到a和b的值发生了变化
print("a = " + a + " b = " + b)
close_out_connection(local_interface, remote_interface)//关闭连接
close_local(local_interface, false)//关闭本地通信协议界面
以上代码是由客户端进程所执行,在服务器端,我们需要运行以下代码接收连接请求并运行call程序块:
variable local_interface, ret
local_interface = ::mfp::paracomp::connect::generate_interface("TCPIP", "192.168.1.107")//服务器端(运行call程序块的进程)地址
ret = ::mfp::paracomp::connect::initialize_local(local_interface, true)
print("initialize_local ret = " + ret + "\n")
//监听连接请求。监听线程将在后台工作。
ret = ::mfp::paracomp::connect::listen(local_interface)
print("listen ret = " + ret + "\n")
//下面这条input语句将阻塞程序的运行。如果服务端代码是一个简单的MFPS脚本并且是在bash或者Windows命令提示符中运行,input语句可以阻止服务器程序的退出所以是必
//不可少的。但是如果是在安卓或者MFP语言的JAVA界面程序中运行,只要安卓应用或JAVA界面程序不退出input语句就是不必要的。因为这种情况下服务器端的进程并没有中止。
input("Press any key to exit\n", "S")
先运行以上服务器端代码,然后在不同的设备中运行客户端代码。在运行之前需要确保客户端和服务器端的地址是正确的。开发者可以看到在服务器端一个Hello ....消息被打印出来。在客户端变量c的新值是一个基于数组的字典,call程序块的返回值54位于该字典中。变量a和b的值也都被更新了。


IP属地:澳大利亚1楼2020-01-27 12:46回复


    来自Android客户端2楼2020-02-16 21:33
    回复