Сами NIF не имеют мьютексов. Вы можете реализовать один на C, и один при загрузке объекта NIF, но это нужно сделать только один раз с загрузочным модулем.
Одна вещь, которая может произойти (и я держу пари, что это то, что происходит), это то, что ваш код C портит планировщик(и) Erlang.
Собственная функция, которая выполняет длительную работу перед возвратом, ухудшит реакцию виртуальной машины и может вызвать странное поведение. Такое странное поведение включает, помимо прочего, чрезмерное использование памяти и неправильную балансировку нагрузки между планировщиками. Странное поведение, которое может возникнуть из-за длительной работы, также может варьироваться в зависимости от выпуска OTP.
и описание того, что означает lengty work
и как вы можете решить эту проблему.
В двух словах (с небольшими упрощениями):
Для ядра создан один планировщик. У каждого есть список процессов, которые он может запускать. Если его список планировщика пуст, он попытается продолжить работу с другого. Это может потерпеть неудачу, если нечего (или недостаточно) еще.
Планировщики Erlang тратят какое-то количество работы в одном процессе, затем перемещаются в другой, тратят там какое-то количество работы и переходят в другое. И так далее, и так далее. Это очень похоже на планирование в системных процессах.
Здесь очень важно рассчитать объем работы. По умолчанию каждому вызову функции назначено некоторое количество сокращений. У дополнения может быть два, у вызывающей функции в вашем модуле будет один, у отправки сообщения также один, у некоторых встроенных может быть больше (например, list_to_binary
). Если мы набираем 2 000 сокращений, мы переходим к другому процессу.
Итак, какова стоимость вашей C-функции? Это только одно сокращение.
Код как
loop() ->
call_nif_function(),
loop().
может занять целый час, но планировщик застрянет на этом одном процессе, потому что он еще не досчитал до 2 000 сокращений. Или, другими словами, он может застрять внутри НИФ без возможности двигаться вперед (по крайней мере, в ближайшее время).
Есть несколько способов обойти это, но общее правило таково: много времени. Поэтому, если у вас есть длинный код C, возможно, вам следует использовать драйверы. Их должно быть намного проще реализовать и управлять ими, чем возиться с NIF.
person
mpm
schedule
23.10.2014