Erlang ports and thread safety

I want to call a C function from an Erlang process through an Erlang port as described here:

In production, I will need multiple Erlang processes calling a C function in parallel, each with a different set of arguments.

My question is, would it be thread-safe at the C function level?

The docs talk about the Erlang governing process creating a "connected process", which sounds like it's responsible for creating an isolated instance of an "external program" (C function).

So it looks like it is C level safe, but I would like to be 100% sure.



source to share

2 answers

It may depend on your implementation, but with ports, the answer is almost definitely yes for the reason you are talking about. If you are using NIF and using shared memory inside the NIF, you will have a definite thread safety issue.

With ports, however, the "control process" acts like a serialization (as in a row) layer, that is, requests are processed one by one, rather than all at the same time. Moreover, I believe (but do not know for sure) that the communication protocol ports also require this serialization.



A port is a program that communicates with the Erlang side using standard input output. Whether stream safety is needed or not depends on the communication protocol used.

If you think the port is an erlang process (which for the erlang side is an abstraction that your erlang code sees), you can implement the protocol, regardless of whether it is sent on every request, it will block until it sends back response, or that you can send multiple requests in parallel and receive responses for all of them asynchronously.

Moving to the C side, the implementation of the first case would be a simple loop doing

  • read command from stdin
  • execute command
  • write the result to stdout
  • go to 1

concurrency is handled on the erlang side as all incoming commands accumulate in the inbox when the port handles one at a time.

For the latter, you will need a mechanism to handle the input messages git remote add origin git @ samuelrivas / dfberl.git asynchronously, I'll use streams here for simplicity:

Main loop:

  • read command from stdin
  • create a thread to process it
  • go to 1

Flow cycle:

  • process command
  • write the result to stdout

Note that threads will need some kind of blocking when writing to stdout, I usually implement this part as another asynchronous queued thread where all other threads are posting the results.

In the second scenario, you will have concurrency on the C side, so you need to take care of thread safety. In the first case, the C side does not handle any concurrency, so thread safety is not an issue here.



All Articles