<Erlang> 关于 long-running(长运行) NIF 函数的研究(三)

使用底层操作系统的线程解决长NIF函数问题

  Erlang运行时使用普通调度器线程来运行Erlang函数和普通NIF函数,通过脏调度器运行脏NIF函数,除了这两种方式外,你还可以使用enif_thread_create或erl_drv_thread_create创建的线程来运行(大部分)独立于Erlang运行时的作业。这是通过将工作分派到另一个由 NIF 库管理的线程,从 NIF 返回并等待结果来完成的。 线程可以使用 enif_send 将结果发送回 Erlang 进程。

typedef struct{
    ErlNifPid pid;
} ThreadArgs;

static void* sleep_thread(void *arg){
    ErlNifPid pid = ((ThreadArgs*)arg)->pid;
    ErlNifEnv *msg_env = enif_alloc_env();
    for(int n = 0; n < 10; n++){
        Sleep(1000);
        enif_send(NULL, &pid, msg_env, enif_make_tuple2(msg_env, make_atom(msg_env, "loop"), enif_make_int(msg_env,n)));
    }
    enif_free_env(msg_env);
    enif_free(arg);
}

static ERL_NIF_TERM test(ErlNifEnv* env, int argc, const ERL_NIF_TERM argv[]){
    ErlNifTid tid;
    ThreadArgs* arg = enif_alloc(sizeof(ThreadArgs));
    enif_self(env, &arg->pid);
    if(enif_thread_create("sleep_thread", &tid, sleep_thread, arg, NULL) != 0){
        enif_free(arg);
        return enif_make_badarg(env);
    }
    return atom_ok;
}
posted @ 2023-03-09 17:37  karl2013  阅读(49)  评论(0)    收藏  举报