我发现Elixir程序可以通过NIFs (native implemented functions)或OS-level ports运行C代码。阅读了这些链接和类似链接后,我不清楚何时使用一种或另一种方法(或完全使用其他方法?),并且对自己和其他新手来说,可以直接进行比较会很好。谁能提供?
最佳答案
什么是端口?
端口基本上是与Erlang VM分开运行的独立程序。 Erlang VM通过标准输入/输出与正在运行的端口进行通信,并且生成的端口位于拥有该端口的Erlang进程的后面,并且可以促进该端口与您的Erlang或Elixir应用程序的其余部分之间的通信。从某种意义上讲,端口是“安全的”,如果端口崩溃,它不会使整个Erlang VM崩溃。
Porcelain作为对Port
模块中已经提供的功能的可能改进和扩展,可能会引起人们的兴趣。 System.cmd/3
在其基础实现中也使用端口。
什么是NIF?
native 内联函数或“NIF”是在本质上由Erlang VM加载并使用某种公开C兼容ABI的语言编写的共享库/DLL中定义的函数。 NIF比端口更有效(因为它们不必通过STDIN
/STDOUT
进行通信)并且在许多方面都更简单(因为您不必处理Elixir和非Elixir代码库之间的数据编码和解码),但是它们的安全性也要差得多; NIF可能会使Erlang VM崩溃,并且长时间运行的NIF可能会锁定Erlang VM(因为调度程序无法推断出 native 代码)。
什么是端口驱动程序?
端口驱动程序是一种将外部代码与Erlang或Elixir代码库集成的中间方法。像NIF一样,它们已加载到Erlang VM中,因此端口驱动程序可能会使整个VM崩溃或挂起。像端口一样,它们的行为类似于Erlang进程。
我什么时候应该使用端口?
什么时候应该使用NIF?
什么时候应该使用端口驱动程序?
你有什么建议吗?
这里要权衡两个方面:
如果要在类似过程的界面后面获得最大的安全性,请使用端口。
如果您想在类似模块的界面后面获得最大的安全性,请选择具有包装
System.cmd/3
或直接使用端口与外部代码进行通信的功能的模块如果要在类似进程的界面后面获得更高的效率,请使用端口驱动程序。
如果要在类似模块的接口(interface)后面获得更高的效率,请使用NIF。
关于c - 在Elixir/Erlang中运行C代码: Ports or NIFs?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/42035912/