Erlang 端口和线程安全

Erlang ports and thread safety

我希望通过 Erlang 端口从 Erlang 进程调用 C 函数,如下所述:

http://www.erlang.org/doc/tutorial/c_port.html

在生产中,我需要多个 Erlang 进程并行调用 C 函数,每个进程都有一组不同的参数。

我的问题是,这在 C 函数级别是线程安全的吗?

文档讨论了创建 'connected process' 的控制 Erlang 进程,听起来好像负责创建 'external program'(C 函数)的独立实例。

所以听起来它在 C 级别是线程安全的,但我想 100% 确定。

TIA

这可能取决于您的实施,但对于 Ports,由于您提到的原因,答案几乎肯定是 "yes"。如果您使用 NIF 并在 NIF 内部使用共享内存,您可能会担心线程安全。

然而,对于端口,"controlling process" 充当序列化(如按系列排列)层,这意味着请求一个接一个地处理,而不是一次处理所有请求。此外,我相信(但不确定)使用的通信协议端口也需要这种串行执行。

端口是使用标准输入输出与 Erlang 端通信的程序。是否需要线程安全取决于你实现的通信协议。

如果你认为端口是一个 erlang 进程(对于 erlang 端来说是你的 erlang 代码看到的抽象),你可以实现一个协议,无论你发送给它的每个请求,它都会阻塞直到它发回响应,或者您可以并行发送多个请求并异步获取所有请求的响应。

在 C 端,前一种情况的实现将是一个简单的循环

  1. 从标准输入读取命令
  2. 处理该命令
  3. 将结果写入标准输出
  4. 转到 1

并发是在 erlang 端处理的,因为当端口一次处理一个命令时,所有传入的命令都会堆积在端口收件箱中。

对于后者,您需要一种机制来处理输入消息 git remote add origin git@bitbucket.org:samuelrivas/dfberl.git 异步,为了简单起见,我将在这里使用线程:

主循环:

  1. 从标准输入读取命令
  2. 产生一个线程来处理它
  3. 转到 1

线程循环:

  1. 处理命令
  2. 将结果写入标准输出

请注意,线程在写入 stdout 时需要某种锁定,我通常将该部分实现为具有异步队列的另一个线程,所有其他线程都将结果发布到该队列。

第二种情况你会在C端有并发,所以你需要关心线程安全。在第一个中,C 端不处理任何并发,因此线程安全在那里不是问题。