gpt4 book ai didi

c - Erlang:阻止 C NIF 调用行为

转载 作者:行者123 更新时间:2023-12-04 11:17:33 25 4
gpt4 key购买 nike

我观察到 C NIF 在被许多 Erlang 进程同时调用时的阻塞行为。可以做成非阻塞的吗?这里有我无法理解的互斥锁吗?

附言在特定的 PID 调用它的情况下,可以通过使其 sleep 一百个微秒来测试基本的“Hello world”NIF。可以观察到调用 NIF 的其他 PID 在执行之前等待该 sleep 执行。

在并发性可能不会造成问题的情况下(例如数组推送、计数器递增),非阻塞行为将是有益的。

我正在分享指向 4 个要点的链接,这些要点分别由 spawnerconc_nif_callerniftest 模块组成。我试图修改 Val 的值,我确实观察到了非阻塞行为。这通过为 spawn_multiple_nif_callers 函数分配一个大整数参数来确认。

链接 spawner.erl , conc_nif_caller.erl , niftest.erl最后 niftest.c .

下面这行是我 Mac 上的 Erlang REPL 打印的。

Erlang/OTP 17 [erts-6.0] [source] [64-bit] [smp:4:4] [async-threads:10] [hipe] [kernel-poll:false] [dtrace]

最佳答案

NIF 本身没有任何互斥量。您可以在 C 中实现一个,当您加载 NIF 的对象时会有一个,但这应该只在加载模块时完成一次。

可能正在发生的一件事(我敢打赌这就是正在发生的事情)是您的 C 代码弄乱了 Erlang 调度程序。

A native function that do lengthy work before returning will degrade responsiveness of the VM, and may cause miscellaneous strange behaviors. Such strange behaviors include, but are not limited to, extreme memory usage, and bad load balancing between schedulers. Strange behaviors that might occur due to lengthy work may also vary between OTP releases.

description lengty work 意味着什么以及如何解决它。

简而言之(几乎没有简化):

为核心创建了一个调度程序。每个人都有一个他可以运行的进程列表。如果一个调度程序列表为空,他将尝试从另一个调度程序列表继续工作。如果没有什么(或不够)静止,这可能会失败。

Erlang 调度程序在一个进程中花费一些工作量,然后转移到另一个进程,在那里花费一些工作量,然后转移到另一个。等等,等等。这与系统进程中的调度非常相似。

这里非常重要的一件事是计算工作量。默认情况下,每个函数调用都分配了一定数量的归约。添加可以有两个,模块中的调用函数将有一个,发送消息也有一个,一些内置可以有更多(如 list_to_binary)。如果我们收集到 2000 个减少,我们将转移到另一个过程。

那么你的 C 函数的成本是多少?这只是一个减少。

代码如下

loop() ->
call_nif_function(),
loop().

可能需要整整一个小时,但调度器会卡在这个过程中,因为他还没有数到 2000 个减少量。或者换句话说,他可能会被困在 NIF 中而无法前进(至少很快)。

有几种方法around this但一般规则是统计 NIF 不应花费很长时间。所以如果你有长时间运行的 C 代码,也许你应该使用 drivers反而。与 NIF 进行修补相比,它们应该更易于实现和管理。

关于c - Erlang:阻止 C NIF 调用行为,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/26531540/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com