Функция Enif_send из проблемы созданного потока
Я пытался вызвать enif_send из созданного потока. В основном, у меня есть процесс erlang, который прослушивает полученное сообщение от моего nif.
Во-первых, в моей функции enif я получил pid моего процесса erlang и произвел его, затем я вызываю enif_send, чтобы отправить сообщение следующим образом:
ErlNifPid* pid = (ErlNifPid*) enif_alloc(sizeof(ErlNifPid));
ErlNifPid * erlang_pid = (ErlNifPid*)argv;
ERL_NIF_TERM pid1 = enif_make_pid(env , erlang_pid);
if(enif_is_pid(env,pid1))
printf(" it's pid\n");
else
printf(" it's not pid\n");
msg_env = enif_alloc_env();
ERL_NIF_TERM replay = (ERL_NIF_TERM) *text;
msg = enif_make_tuple(msg_env, replay);
if(enif_send(NULL, erlang_pid, msg_env,msg))
printf(" send succeed\n");
else
printf(" send failed\n");
До этой стадии я могу отправить сообщение в мой процесс erlang.
После этого я создал enif_thread и передал ему env и pid в качестве параметров. Я попытался вызвать enif_send из моего потока, например:
ERL_NIF_TERM pid1 = enif_make_pid(conn->env , conn->pid);
if(enif_is_pid(conn->env,pid1))
printf("it's pid\n");
else
printf(" it's not pid\n");
for (int i=0;i<index;i++)
{
msg_env = enif_alloc_env();
msg = enif_make_int(msg_env, 1);
if(enif_send(conn->env, conn->pid, msg_env,msg))
printf(" send succeed\n");
else
printf(" send failed\n");
Но когда я проверил pid с помощью enif_is_pid, я получил недопустимый pid, даже если это тот же pid, который был проверен в функции, которая порождает поток, поэтому отправка не удалась. Любая идея, пожалуйста?
1 ответ
В качестве документации для enif_send
государства, env
параметр должен быть NULL
когда функция вызывается из созданного потока.
Кстати, трудно увидеть, не видя весь код, но эта часть кода, которую вы показываете, может быть проблематичной:
ErlNifPid * erlang_pid = (ErlNifPid*)argv;
ERL_NIF_TERM pid1 = enif_make_pid(env, erlang_pid);
Если вы хотите, чтобы pid вызывающего абонента, вы должны использовать enif_self
функция или если pid передается в NIF в качестве аргумента, вы должны извлечь его, используя enif_get_local_pid
, Например, если это первый аргумент, передаваемый вызывающей стороной Erlang:
ErlNifPid pid;
if (!enif_get_local_pid(env, argv[0], &pid))
return enif_make_badarg(env);
Затем вы можете скопировать его для использования в созданном потоке отправки.