Why does the nif function block the Erlang VM from scheduling other processes?

941 views Asked by At

When the Erlang VM beam runs some code written in C,the other processes written in Erlang was not scheduled. For example:

static ERL_NIF_TERM
        nifsleep(ErlNifEnv* env, int argc, const ERL_NIF_TERM argv[])
        {
            sleep(10);
            return enif_make_atom(env, "ok");
        }

when you call this C function in Erlang,the other processes was not schedulling normally. I want to know why? Is this a feature or is limited by the implementation(that is,this is a bug)?

The address of the code above is in:https://github.com/davisp/sleepy

1

There are 1 answers

0
ppolv On

beam processes are not mapped to OS threads directly. There is normally 1 scheduler per core. Your call to

sleep(10);

is blocking the scheduler that executed it (as expected, otherwise it would have to intercept that call somehow to make it non-blocking), and so the scheduler can't execute any other erlang process until the call returns. Long running nif are strongly discouraged. A quick google is enough to find many references, see for example http://www.erlang.org/doc/man/erl_nif.html#lengthy_work

http://osdir.com/ml/erlang-questions-programming/2013-02/msg00275.html

http://ninenines.eu/articles/erlang-scalability

for comprehensive info about how the scheduler work, see http://jlouisramblings.blogspot.com.ar/2013/01/how-erlang-does-scheduling.html