NodeJS Addon 多线程

Mac版本客户端准备使用electron实现,需要对现有的C API的IM SDK 做NodeJS封装,提供Javascript接口。

使用Nan,遇到的问题主要是NodeJS是libuv defalut_loop 单线程的, SDK有自己的线程,C++层 V8的任何操作必须在主线程操作,不然就直接崩溃, 不像lua 加个锁不同线程都能进去。libuv 唯一线程安全的接口是uv_async_send, 也就只能用它解决问题了。

SDK -> NodeJs 调用流程:

1. SDK 实例初试化时

初试话一个uv_async_t:

uv_async_init(uv_default_loop(), &uv_async, node_event_process);

注意必须在主线程执行

2.  将参数存放在SDK实例对象上

3.  唤醒主线程

uv_async_send(&uv_async)

libuv 在UNIX下的实现是,uv_async_init时创建一个namepipe fd, 在epoll等待,send时就是往fd写入数据,epoll就会返回。

这个时候node 执行脚本完成也不会退出了。

在Win下不一样用的IOCP完成。

要注意的是uv_async_send每次调用并不保证都会执行回调,只保证能唤醒线程,不能作为调用方式。

4. std::condition_variable.wait()

5. 主线程唤醒,读取SDK实例参数执行调用

通过V8接口,调用JSON库,将参数解析为V8 Object对象

通过CallID查找事务回调的CallBack Function,或者提供bind方法绑定的Callback Function,执行调用就会返回Javascript世界开始执行

6. 执行完成,将返回值放到SDK实例上

返回v8::Local<v8::Value> 需先处理为自己的类型,传递到SDK线程读取会导致崩溃

7. std::condition_variable.notify_one()  唤醒SDK线程继续执行

8. SDK wait() 继续执行,读取返回值

这是同步执行方案,异步执行的话需要引入队列,同时实现这两种方案外加注册登陆消息接口500行C++,Javascript可以直接requre动态库使用,NodeJs Addon 封装还是很轻量级的。

上一篇:Android快乐贪吃蛇游戏实战项目开发教程-05虚拟方向键(四)四个三角形按钮


下一篇:Linux中Apache服务器的简单配置