Почему функция nif блокирует виртуальную машину Erlang от планирования других процессов?

Когда луч Erlang VM запускает некоторый код, написанный на C, другие процессы, написанные на Erlang, не планируются. Например:

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

когда вы вызываете эту функцию C в Erlang, другие процессы не планируются нормально. Я хочу знать, почему? Является ли это фичей или ограничено реализацией (то есть это баг)?

Адрес приведенного выше кода находится в: https://github.com/davisp/sleepy.


person user1535183    schedule 12.08.2013    source источник


Ответы (1)


процессы луча не сопоставляются напрямую с потоками ОС. Обычно на каждое ядро ​​приходится 1 планировщик. Ваш звонок в

сон (10);

блокирует планировщик, который его выполнил (как и ожидалось, иначе ему пришлось бы каким-то образом перехватывать этот вызов, чтобы сделать его неблокирующим), и поэтому планировщик не может выполнить какой-либо другой процесс erlang, пока вызов не вернется. Длительные нифы настоятельно не рекомендуются. Достаточно быстро поискать в Google, чтобы найти много ссылок, см., например, 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

исчерпывающую информацию о работе планировщика см. на странице http://jlouisramblings.blogspot.com.ar/2013/01/how-erlang-does-scheduling.html

person ppolv    schedule 12.08.2013