我正在编写一个仅由一个Erlang进程使用的Erlang C NIF。我想创建一个包含指针数组的结构。我需要在进程'调用NIF之间存在这个。
我需要了解的是从Erlang NIF方面采用这种方法的正确方法。我想在所有功能之外编写一个结构,以便所有人都可以访问它。当我在一次打电话给NIF创建它,然后回来使用它与另一个NIF调用时,它似乎工作得很好。
我担心这可能是因为进程保持在调度线程的本地,因此不必将结构和底层数组移动到内存中。
我是否应该在函数中使用erlang:memalloc并且一起避免全局变量,或者保持与全局结构一样?
可能会返回指向包含所有数据的单个数组的指针吗?
答案 0 :(得分:4)
您当然可以返回指向包含数据的单个数组的指针;要做到这一点,请看ErlNifResourceType。您可以将其传递回调用的erlang进程,然后在随后的NIF调用中将其传递回给您。这将确保一次只有一个线程对您的数据进行操作(假设只有一个进程拥有该资源的副本;它不是您想要共享的内容,特别是如果它包含指针)。
您也可以将其编码为erlang列表,但这可能效率非常低。
话虽这么说, 可以 使用来自NIF的共享内存。例如,这是使用共享数据实现为NIF的ets-like database。
您必须记住,您正在访问共享资源。 NIF API提供thread creation,thread specific data,mutexes,conditions和read/write locks。您甚至可以从NIF创建的线程向erlang进程发送消息(如果长时间运行NIF调用,实际上这是您希望如何实现它以防止调度问题)。
根据您的要求,您可能最好使用ErlNifResource类型,而不是搞乱多线程和共享资源控制。从技术上讲,如果您只使用一个erlang进程,则可以将其保留为全局变量(读取:共享资源),而不会产生任何有害的副作用。话虽这么说,事情发生了变化,当你试图使用来自多个进程的代码时,你不希望成为某人头疼的原因。无论使用哪种方法,都要确保它的线程安全。