Проблемы с Erlang NIF и потоками

У меня есть небольшая проблема с потоками в Erlang NIFs. Вы можете просмотреть мой код здесь: http://pastebin.com/HMCj24Jp. Проблема в том, что когда я запускаю поток, он принимает некоторые аргументы и запускает функцию generate_binary. Это нормально, но когда я пытаюсь прочитать аргументы, все вылетает.

Возможно, это не самая сложная проблема, но я не смог найти никакой документации по этому поводу, поэтому я надеюсь, что некоторые из вас могут знать ответ.

1 ответ

Решение

Ваш generate_buffer() NIF создает поток для вызова generate_binary() но вызывающий NIF не ждет окончания созданного потока. Поток только что создан и, вероятно, все еще работает к моменту возврата NIF, хотя это будет недетерминировано, поскольку потоки в целом. Вы, вероятно, сбой эмулятора Erlang BEAM, потому что generate_binary() после попытки вызова в систему времени выполнения Erlang generate_buffer() вернулся, ужасно запутав бедняжку.

Теперь, даже если предположить, что вы исправите это, чтобы заставить его делать то, что вы хотели, я не думаю, что вам вообще следует использовать явные нативные потоки.

Во-первых, предполагается, что Erlang NIF выглядят как обычные функции Erlang, отличающиеся только тем, что они написаны на другом языке. Функции Erlang не порождают отдельные потоки выполнения, а затем возвращаются, оставляя этот поток работающим. За исключением тех, которые имеют дело с вводом / выводом и постоянным хранением данных, функции Erlang являются детерминированными и ссылочно прозрачными. Ваш NIF не является ни тем, ни другим. Таким образом, даже если это сработало, это все равно "неправильно" в том смысле, что оно нарушает ожидания опытного программиста на Erlang.

Во-вторых, если вам нужна многопроцессорность, Erlang уже предлагает идею процессов. Если ваш NIF действительно выполняет так много работы, что может извлечь выгоду из многопроцессорности, почему бы не переработать ваш NIF, чтобы он мог работать с поддиапазоном данных, а затем вызывать его несколько раз, по одному из нескольких процессов Erlang? Тогда вам не нужны явные нативные потоки; эмулятор BEAM создаст оптимальное количество потоков для вас, прозрачно.

В-третьих, накладные расходы на создание потока приведут к снижению производительности, если время жизни потока будет продолжаться только в течение одного вызова Erlang NIF, как вы и предполагали. Это еще одна причина, по которой процессы Эрланга будут более эффективными.

Другие вопросы по тегам