2017-02-23 68 views
1

我試圖從創建的線程調用enif_send。 主要是,我有一個erlang過程,它收聽從我的nif發出的收到的消息。創建線程問題的Enif_send函數

首先,在我的危宿功能我得到了我的Erlang進程的PID,我投它,然後我打電話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相同,所以發送失敗。 有什麼想法嗎?

回答

2

documentation for enif_send所述,當從創建的線程調用該函數時,env參數應爲NULL

順便說一句,這是很難說沒有看到所有的代碼,但是這部分代碼顯示您可能會出現問題:

ErlNifPid * erlang_pid = (ErlNifPid*)argv; 
ERL_NIF_TERM pid1 = enif_make_pid(env, erlang_pid); 

如果你想呼叫方的PID,您應該使用the enif_self function或如果將pid作爲參數傳遞給NIF,則應使用enif_get_local_pid將其解壓。例如,如果是從二郎調用者傳遞的第一個參數:

ErlNifPid pid; 
if (!enif_get_local_pid(env, argv[0], &pid)) 
    return enif_make_badarg(env); 

然後,您可以複製它在創建發送線程使用。