Ihre generate_buffer()
NIF erstellt einen Thread zum Aufruf generate_binary()
, aber die aufrufende NIF wartet nicht auf den neu erstellten Thread zu beenden. Der Thread wird gerade erstellt und läuft wahrscheinlich noch, wenn NIF zurückkehrt, obwohl dies nicht deterministisch ist, da Threads im Allgemeinen sind. Sie stürzen wahrscheinlich den Erlang BEAM-Emulator ab, weil generate_binary()
aus ist, versucht, in das Erlang-Laufzeitsystem zu rufen, nachdem generate_buffer()
zurückgekehrt ist, das arme Ding fürchterlich verwirrend.
Jetzt, auch wenn Sie dies beheben, um es tun zu lassen, was Sie wollten, ich glaube nicht, dass Sie explizite native Threads hier überhaupt verwenden sollten.
Zuerst sollen Erlang-NIFs wie normale Erlang-Funktionen aussehen und sich nur darin unterscheiden, dass sie in einer anderen Sprache geschrieben sind. Erlang-Funktionen erzeugen keine separaten Ausführungsthreads und kehren dann zurück, wodurch dieser Thread ausgeführt wird. Außer denen, die sich mit E/A und persistentem Datenspeicher befassen, sind Erlang-Funktionen deterministisch und referentially transparent. Ihre NIF ist weder. Also, selbst wenn es funktioniert, ist es immer noch "falsch" in dem Sinne, dass es die Erwartungen eines erfahrenen Erlang-Programmierers verletzt.
Zweitens, wenn Sie Multiprocessing benötigen, bietet Erlang bereits die Idee von Prozessen. Wenn Ihr NIF wirklich so viel Arbeit leistet, dass es vom Multiprocessing profitieren kann, warum sollten Sie Ihren NIF nicht so bearbeiten, dass er an einem Teilbereich der Daten arbeiten kann, und ihn dann mehrmals aus mehreren Erlang-Prozessen aufrufen? Dann brauchen Sie keine expliziten nativen Threads. Der BEAM-Emulator erstellt die optimale Anzahl von Threads transparent für Sie.
Drittens wird Thread-Erstellungs-Overhead die Leistung zerstören, wenn sich die Lebensdauer des Threads nur im Verlauf eines einzelnen Erlang-NIF-Aufrufs erstreckt, so wie es aussieht. Dies ist ein weiterer Grund, warum Erlang-Prozesse hier effizienter sind.