我一直在阅读Principles of Computer System Design
(Saltzer& Kaashoek),其中一个章节是关于模块化的。例如:
现在这些都非常标准,并且是大多数OO语言的工作方式。但是,他们提到了更严格的要求,例如:
现在这些要求对我来说非常有意义,并且可以做很多工作来阻止错误传播到整个大型程序中并使其全部崩溃。
然而,他们建议的方法,将所有内容分解为客户端/服务器进程,对于许多目的而言似乎有点过分。编写你要模块化的所有作为客户端/服务器似乎都是:
例如,我希望能够将工作委托给我的Math模块,并限制执行时间和内存使用,但我真的不想创建单独的Math 服务器在后台运行只是为了这些好处!此外,与直接过程调用相比,IPC消息传递开销(计算和延迟)肯定相当大。
是否有任何语言在进程中提供这种模块化?作为直接过程调用的紧耦合和多进程客户端 - 服务器设计的开销之间的介于两者之间?我想象的方式,而不是:
y = Math.sin(x)
让我对Math
模块中的无限循环和堆栈溢出开放,我想做类似的事情
y = try(maxMemory=1024kb, maxTime=12ms){
Math.sin(x)
}catch(Anything){
0
}
如果0
内的任何内容失败,则会将y设置为默认值(Math.sin
)。无效的输入,错误,无限循环,运行时异常,任何事情。在某种语言中是否存在这样的事情,如果没有,为什么?在我看来,在各种各样的地方都会有非常有用的东西。
答案 0 :(得分:1)
您可以使用Racket:
在sandbox library中执行此操作> (require racket/sandbox)
> (define x 0) ;; some input value
> (call-with-limits 0.012 ;; 12 ms
1 ;; 1 MB
(lambda () (sin x)))
0
> (call-with-limits 1 ;; 1 sec
1 ;; 1 MB
(lambda () (sleep 2) 'done))
with-limit: out of time
> (call-with-limits #f ;; no time limit
1 ;; 1 MB
(lambda ()
(let loop ()
(cons (make-vector 10000) (loop)))))
with-limit: out of memory
代码在单独的轻量级Racket(“绿色”)线程中运行(不是单独的OS进程)。
最后两种情况会引发异常,如果要替换替代值,可以捕获异常。
使用沙箱库,您还可以执行更强大的功能,例如设置评估程序,限制对少量已批准库的访问,限制文件系统和网络访问等。
另一方面,这比普通的函数调用更昂贵。在实践中,您需要确定您信任哪些组件以及您不信任哪些组件。或者您可能应该查看支持对其他要求进行静态验证的系统。