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 封装还是很轻量级的。
NodeJS Addon 多线程的更多相关文章
- NodeJS Addon 多线程通信
某个产品的Mac客户端计划基于electron实现,因为现有SDK有C API,原理上用NodeJS Addon来封装成JS API就可使用了.但涉及到与Addon多线程交互,翻找资料没能找到到底该怎 ...
- 使用neon 开发nodejs addon
备注:开发使用的是mac 系统,需要安装rust nodejs .python2.7 Xcode 1. 安装neon npm install -g neon-cli 2. 创建简单项目 neon ...
- nodejs addon/module
https://github.com/nodejs/node-addon-examples https://github.com/nodejs/node-gyp http://skitr.com/20 ...
- Nodejs的多线程
转: http://snoopyxdy.blog.163.com/blog/static/60117440201349352443/
- 异步编程系列第02章 你有什么理由使用Async异步编程
p { display: block; margin: 3px 0 0 0; } --> 写在前面 在学异步,有位园友推荐了<async in C#5.0>,没找到中文版,恰巧也想提 ...
- 如何用 Electron + WebRTC 开发一个跨平台的视频会议应用
在搭建在线教育.医疗.视频会议等场景时,很多中小型公司常常面临 PC 客户端和 Web 端二选一的抉择.Electron 技术的出现解决了这一难题,只需前端开发就能完成一个跨平台的 PC 端应用.本文 ...
- 记录开发Nodejs c++ addon的一些经验(三、关于node-gyp)
关于node-gyp如何进行编译,我想它的官网已经说的很详细了: https://github.com/nodejs/node-gyp 但是我感觉关于binding.gyp文件的语法规则还是说的不明确 ...
- 记录开发Nodejs c++ addon的一些经验(一、技术栈)
Nodejs c++ addon 是用c++去编写Nodejs的插件 技术栈: 1.node-gyp 一个用于把c++文件编译成node可执行文件的库 2.v8 google v8引擎 用于处理c++ ...
- 锋利的NodeJS之NodeJS多线程
最近刚好有朋友在问Node.js多线程的问题,我总结了一下,可以考虑使用源码包里面的worker_threads或者第三方的模块来实现. 首先明确一下多线程在Node.js中的概念,然后在聊聊work ...
随机推荐
- 关于 bind 你可能需要了解的知识点以及使用场景
不看不知道,一看吓一跳,已经整整一个月没有更新 underscore 源码解读系列文章了.前面我们已经完成了 Object ,Array,Collection 上的扩展方法的源码剖析,本文开始来解读 ...
- Css--深入学习之折角效果
本文是作者从别的网站和文章学习了解的知识,简单做了个笔记,想要学习更多的可以参考这里:[css进阶]伪元素的妙用--单标签之美,奇思妙想 代码: /*建立一个带圆角的矩形,并使用线性渐变将其从左到底透 ...
- redis配置文件详解
基于redis2.4版本的配置文件. # 注意单位问题:当需要设置内存大小的时候,可以使用类似1k.5GB.4M这样的常见格式:## 1k => 1000 bytes# 1kb => 10 ...
- js-读取复选框
js: var obj = document.getElementsByName("yk"); var check_val = []; for(k in obj){ if(obj[ ...
- 解决vs崩溃 无法打开工程 新建工程显示未找到约束
一般是因为windows更新引起的,可以删除与.net framework有关的更新补丁如果补丁太多可以试试如下方法: 解决方法: 1.关闭VS: 2.去C:/Users/<your users ...
- UEFI模式安装Win10和Linux双系统
最近心血来潮,想装一个Linux.Windows双系统,吸取上次安装的经验,这次一定都要使用UEFI模式启动,需要注意的是必须是支持此种启动模式的系统(一般解压之后都有efi文件夹不需要刻录),这次遇 ...
- Swift中的类型转换
写在前面:1,类型转换的两种方式 2,as!和as?的用法 3,类型判断中 is和===的用法 类型转换方式一,利用类型的构造器进行转换 let str = " var i = Int(st ...
- Yii2.0 对的一些简单的操作
1: 此方法返回 ['name' => 'daxia'] 的所有数据: User::find()->where(['name' => 'daxia'])->all(); 2: ...
- RabbitMQ学习
参考链接:http://www.cnblogs.com/leocook/p/mq_rabbitmq_0.html
- JQuery中$.each 和$(selector).each()的区别详解
PS:晚上在写页面时,发现了一个问题,$.each 和$(selector).each()有哪些区别?百度搜索关键词,首页显示出来一些前人的经验,总结一下,发上来. 1.$(selector).eac ...