Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/multithreading/4.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Erlang生成大量C进程_C_Multithreading_Lua_Erlang_Ffi - Fatal编程技术网

Erlang生成大量C进程

Erlang生成大量C进程,c,multithreading,lua,erlang,ffi,C,Multithreading,Lua,Erlang,Ffi,我一直在研究如何在Erlang中嵌入语言(让我们以Lua为例)。这当然不是一个新的想法,有很多图书馆可以做到这一点。然而,我想知道是否有可能启动一个状态为Lua修改的Genserver。这意味着一旦启动Genserver,它将启动一个(长时间运行的)Lua进程来操作Genserver的状态。我知道这也是可能的,但我想知道我是否能产生1000、10000甚至100000个这样的进程 我对这个话题不太熟悉,但我做了一些研究。 (如果我在这些选项中有任何一个错误,请纠正我) TLDR;跳到最后一段 第

我一直在研究如何在Erlang中嵌入语言(让我们以Lua为例)。这当然不是一个新的想法,有很多图书馆可以做到这一点。然而,我想知道是否有可能启动一个状态为Lua修改的Genserver。这意味着一旦启动Genserver,它将启动一个(长时间运行的)Lua进程来操作Genserver的状态。我知道这也是可能的,但我想知道我是否能产生1000、10000甚至100000个这样的进程

我对这个话题不太熟悉,但我做了一些研究。 (如果我在这些选项中有任何一个错误,请纠正我)

TLDR;跳到最后一段

第一个选项:NIFs:

这似乎不是一个选项,因为它将阻止当前进程的Erlang调度程序。如果我想产生大量的这些,它将冻结整个运行时

第二个选项:端口驱动程序:

它类似于NIF,但通过将数据发送到指定的端口进行通信,该端口还可以将数据发送回Erlang。这很好,尽管这似乎也会阻止调度程序。我尝试了一个库,它也为您提供了锅炉平台,但在生成10个进程之后,它似乎阻止了调度程序。我还研究了Erlang文档中的postgresql示例,该示例据说是异步的,但我无法使示例代码正常工作(R13?)。甚至可以在不阻塞运行时的情况下运行尽可能多的端口驱动程序进程吗

第三个选项:C节点:

我认为这很有趣,并想尝试一下,但显然“ErlangLua”项目已经做到了这一点。这很好,因为如果出现问题并且进程被隔离,它不会使您的ErlangVM崩溃。但为了实际生成单个进程,您需要生成整个节点。我不知道这有多贵。我也不确定连接集群中节点的限制是什么,但我不认为自己会产生100000个C节点

第四个选项:端口:

起初我认为这和端口驱动程序是一样的,但实际上是不同的。生成一个进程,该进程执行应用程序并通过STDIN和STDOUT进行通信。这对于生成大量进程来说非常有效,而且(我认为?)它们不会对ErlangVM造成威胁。但是,如果我要通过STDIN/STDOUT进行通信,为什么还要从一开始就使用嵌入式语言呢?也可以使用任何其他脚本语言


因此,在我不熟悉的领域进行了大量研究之后,我得出了这个结论。您可以将Genserver作为一个“实体”,其中AI是用Lua编写的。这就是为什么我希望每个实体都有一个流程。我的问题是如何生成许多与长时间运行的Lua进程通信的GenServer?这可能吗?我应该以不同的方式解决我的问题吗?

如果您可以让Lua代码——或者更准确地说,它的底层本机代码——与Erlang VM合作,那么您有几个选择

考虑Erlang VM最重要的功能之一:在一组相对较小的调度程序线程中管理(可能大量)Erlang轻量级进程的执行。它使用多种技术来了解某个进程何时已用完其时间片或正在等待,因此应将其调度出去,以使另一个进程有机会运行

您似乎在问如何让本机代码在VM中以其喜欢的方式运行,但正如您已经暗示的,本机代码可能会给VM带来问题的原因是,它没有实际的方法来阻止本机代码完全接管调度程序线程,从而阻止常规Erlang进程的执行。因此,本机代码必须协同将调度程序线程返回到VM

对于较老的NIF,此类合作的选择是:

  • 将在调度程序线程上运行NIF调用的时间保持在1ms或更短
  • 创建一个或多个专用线程。将每个长时间运行的NIF调用从其调度程序线程转换到私有线程执行,然后将调度程序线程返回到VM
  • 这里的问题是,并非所有调用都能在1ms或更短的时间内完成,而且管理私有线程可能容易出错。为了解决第一个问题,一些开发人员将工作分解为多个块,并使用Erlang函数作为包装器来管理一系列简短的NIF调用,每个调用完成一个块的工作。至于第二个问题,尽管它有内在的困难,但有时你无法避免它

    在Erlang 17.3或更高版本上运行的NIF还可以使用。要使用此功能,本机代码必须能够在块中完成其工作,这样每个块都可以在通常的1ms NIF执行窗口内完成,类似于前面提到的方法,但不需要人工返回Erlang包装器。My提供了许多有关这方面的详细信息

    Erlang17还带来了一个实验性的特性,默认情况下是关闭的,称为脏调度器。这是一组VM调度程序,它们没有与常规调度程序相同的本机代码执行时间约束;在那里的工作可以在不中断正常VM操作的情况下基本上无限期地阻塞

    脏调度器有两种类型:用于CPU绑定工作的CPU调度器和用于I/O绑定工作的I/O调度器。在编译为启用脏调度程序的VM中,默认情况下,脏CPU调度程序的数量与常规调度程序的数量相同,并且有10个I/O调度程序。可以使用命令行开关更改这些数字,但请注意,为了防止常规调度程序不足,您的CPU调度程序不能比常规调度程序更脏。应用程序使用earl提到的相同的
    enif\u schedule\u nif
    函数