Erlang NIF 和线程的问题
我在 Erlang NIF 中的线程方面遇到了一些问题。您可以在此处查看我的代码:http://pastebin.com/HMCj24Jp。问题是,当我启动线程时,它需要一些参数并启动 generate_binary 函数。这没关系,但是当我尝试阅读参数时,一切都会崩溃。
这可能不是最复杂的问题,但我找不到任何有关此问题的文档,所以我希望你们中的一些人可能知道答案。
I have a little problem with threads in Erlang NIFs. You can view my code here: http://pastebin.com/HMCj24Jp. The problem is that when I starting the thread it takes some arguments and starts the generate_binary function. This is okay but when I'm trying to read the arguments everything crashes.
It's perhaps not the most complex problem, but I could not find any documentation about this so I hope some of you might know the answer.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
您的
generate_buffer()
NIF 正在创建一个线程来调用generate_binary()
,但调用 NIF 不会等待新创建的线程完成。线程刚刚被创建,并且在 NIF 返回时可能仍在运行,尽管这将是不确定的,就像线程一般一样。您可能会导致 Erlang BEAM 模拟器崩溃,因为在generate_buffer()
返回后,generate_binary()
无法尝试调用 Erlang 运行时系统,这让这个可怜的东西感到困惑。可怕的是。现在,即使假设您修复了此问题以使其执行您想要的操作,我认为您根本不应该在此处使用显式本机线程。
首先,Erlang NIF 应该看起来像常规的 Erlang 函数,不同之处仅在于它们恰好是用不同的语言编写的。 Erlang 函数不会生成单独的执行线程,然后返回,让该线程继续运行。除了那些处理 I/O 和持久数据存储的函数之外,Erlang 函数是确定性的,并且是参照透明的。你的 NIF 两者都不是。因此,即使它有效,它仍然是“错误的”,因为它违反了经验丰富的 Erlang 程序员的期望。
其次,如果你需要多处理,Erlang 已经提供了进程的概念。如果您的 NIF 确实会做如此多的工作,以至于它可以从多处理中受益,为什么不重新设计您的 NIF,使其可以处理数据的子范围,然后多次调用它,每次从多个 Erlang 进程调用一次?那么你就不需要显式的本机线程; BEAM 模拟器将透明地为您创建最佳数量的线程。
第三,如果线程的生命周期仅在单个 Erlang NIF 调用的过程中延长,那么线程创建开销将会降低性能,正如您实际希望的那样。这是 Erlang 进程在这里更加高效的另一个原因。
Your
generate_buffer()
NIF is creating a thread to callgenerate_binary()
but the calling NIF doesn't wait for the newly-created thread to finish. The thread just gets created and likely is still running by the time the NIF returns, though this will be nondeterministic, as threads are in general. You're probably crashing the Erlang BEAM emulator becausegenerate_binary()
is off trying to call into the Erlang run-time system aftergenerate_buffer()
has returned, confusing the poor thing horribly.Now, even assuming you fix this to make it do what you wanted, I don't think you should be using explicit native threads here at all.
First, Erlang NIFs are supposed to look like regular Erlang functions, differing only in that they happen to be written in a different language. Erlang functions don't spawn separate threads of execution, then return, leaving that thread running. Excepting those that deal with I/O and persistent data storage, Erlang functions are deterministic and referentially transparent. Your NIF is neither. So, even if it worked, it's still "wrong" in the sense that it violates an experienced Erlang programmer's expectations.
Second, if you need multiprocessing, Erlang already provides the idea of processes. If your NIF will really do so much work that it can benefit from multiprocessing, why not rework your NIF so it can work on a subrange of the data, then call it multiple times, once each from a number of Erlang processes? Then you don't need explicit native threads; the BEAM emulator will create the optimal number of threads for you, transparently.
Third, thread creation overhead is going to kill performance if the lifetime of the thread only extends over the course of a single Erlang NIF call, as it seems you actually intended. This is another reason Erlang processes will be more efficient here.