2

我正在编写一个 Erlang C NIF,它只会被一个 Erlang 进程使用。我想创建一个包含指针数组的结构。我需要它存在于进程对 NIF 的调用之间。

我需要了解的是从 Erlang NIF 方面执行此方法的正确方法。我正在考虑在所有函数之外编写一个结构,以便所有人都可以访问它。当我在对 NIF 的一次调用中创建它,然后返回并在对 NIF 的另一次调用中使用它时,它似乎工作得很好。

我担心这可能是因为进程停留在调度线程的本地,因此不必在内存中移动结构和底层数组。

我应该在函数中使用 erlang:memalloc 并避免一起使用全局变量,还是保持原样使用全局结构?

可能返回一个指向包含我所有数据的单个数组的指针?

4

1 回答 1

4

您当然可以返回一个指向包含您的数据的单个数组的指针;为此,请查看ErlNifResourceType。您将把它传回给调用erlang进程,然后它会在随后的NIF调用中将它传回给您。这将确保一次只有一个线程在您的数据上运行(假设只有一个进程拥有资源的副本;这不是您想要共享的东西,尤其是在它包含指针的情况下)。

您也可以将其编码为 erlang 列表,但这可能效率非常低。

话虽如此,您可以使用 NIF 中的共享内存。例如,这是一个使用共享数据实现为 NIF的类似 ets 的数据库。

您只需要记住您正在访问共享资源。NIF API 提供线程创建线程特定数据互斥体条件读/写锁。您甚至可以从 NIF 创建的线程向 erlang 进程发送消息(在长时间运行的 NIF 调用的情况下,这实际上是您希望实现它以防止调度问题的方式)。

鉴于您的要求,您最好使用 ErlNifResource 类型,而不是使用多线程和共享资源控制。从技术上讲,如果您只使用一个 erlang 进程,则可以将其保留为全局变量(阅读:共享资源),而不会产生任何有害的副作用。话虽如此,事情会发生变化,当某人尝试从多个进程中使用您的代码时,您不希望成为他们头疼的原因。无论您最终使用哪种方法,请确保它是线程安全的。

于 2013-01-22T21:07:31.190 回答