我正在写一个Erlang C NIF,它只会被一个Erlang进程使用。我想创建一个结构体来保存一个指针数组。我需要它存在于进程对NIF的调用之间。
我需要了解的是从Erlang NIF方面做这种方法的正确方法。我想写一个结构之外的所有功能,所以它的所有访问。当我在对NIF的一次调用中创建它,然后回来并与对NIF的另一次调用一起使用它时,它似乎工作得很好。
我担心这可能是因为进程保持在调度线程的本地,因此不需要移动内存中的结构体和底层数组。
我应该使用erlang:memalloc从一个函数和避免全局在一起,还是保持与全局结构?
可能返回一个指针到一个数组包含我所有的数据?
你当然可以返回一个指向包含你的数据的单个数组的指针;要做到这一点,看一下ErlNifResourceType。您将把它传递回调用erlang的进程,然后在随后的NIF调用中将它传递回给您。这将确保一次只有一个线程在操作您的数据(假设只有一个进程拥有资源的副本;这不是你想要分享的东西,特别是如果它包含指针)。
您也可以将其编码为erlang列表,但这可能会非常低效。
也就是说,可以使用来自NIF的共享内存。例如,下面是一个类似ets的数据库,使用共享数据实现为NIF。你只需要记住你正在访问共享资源。NIF API提供线程创建、线程特定数据、互斥锁、条件和读/写锁。您甚至可以从NIF创建的线程向erlang进程发送消息(在长时间运行的NIF调用的情况下,这实际上是您希望实现它以防止调度问题的方式)。
考虑到您的需求,您可能最好使用ErlNifResource类型,而不是使用多线程和共享资源控件。从技术上讲,如果您只使用一个erlang进程,您可以将其保留为全局变量(即:共享资源),而不会产生任何有害的副作用。话虽如此,事情总是在变化的,您也不希望在以后有人试图从多个进程中使用您的代码时,给他们带来麻烦。无论你使用哪种方法,确保它是线程安全的。