前言

​ 这几天在爱智官网看了下JSRE其他的Api,看了一个比较有意思的模块 - 多任务模块task,大致看了下他们的接口说明和案例,感觉和多线程差不多,然后就准备去看下实现方式,找了很久没有找到源码(╬ ̄皿 ̄),问了他们那边工作人员才知道目前源码还没有开放出来,那我也就只能 wait, wait ...

凌晨3点半的我又醒来继续敲代码了,可信度看人品!!!

在没有得到源码加持的我,只能轻装上阵,这装备感觉承受不住你们的第一轮笔伐 ... 希望在座的各位可以做个人,啊不,是做个猿(媛)!

多任务介绍

​ 鄙人经过九牛一毛之力,终于给大家带来了第一手资讯。据可靠情报得知(PS:其实也就从他们官网直接复制了一点官方介绍过来(≖ᴗ≖)✧):

JSRE中每一个创建的Task都是操作系统中的一个独立线程,操作系统可以根据调度策略独立调度,用来提高应用程序的并行性。Node.js等运行时平台虽然通过多线程异步代理并行化,但核心程序进程无法并行化,程序员可控性太低(这点我比较赞同),没有可控策略。除此之外,多任务模块还提供了更好的应用代码解耦。应用模块分离和开发,更容易构建更复杂的大规模应用。

​ 花了我3秒的时间敲出了上面的一大片内容,感慨自己从三岁就开始敲键盘的努力没有白费!(ಥ﹏ಥ)。

​ 我们都知道Node.js是单线程,但这仅仅指js执行主线程是单线程,其他异步IO和事件驱动相关的线程通过libuv来实现内部的线程池和线程调度,本身只负责不断的往返调度,并没有进行真正的I/O操作,从而实现异步非阻塞I/O。

【问题】:这边说JSRE中每个task都是一个独立的线程,难道JSRE本身就支持多线程的嘛?

【答】:不用想了,我自己也不是很清楚,在官网没有找到一个准确的答案,那我们就接着继续实践出真知!

实例测试

1、同步执行

  • 测试代码:
// main.js
...
console.info('start'); // 模拟3s耗时操作
let t = 0;
while (t < 3000) {
console.warn('wait...');
sys.sleep(1000);
t += 1000;
} console.info('end');
...
  • 运行结果:



    我们在入口文件main.js中加入以上测试代码,我们都知道js代码运行阶段都是从上往下开始顺序执行的,我们在主线程中添加了一段3秒的阻塞代码,当然在实际项目中也许一个服务启动时耗时更多。

VSCode输出窗口中我们可以看到日志是顺序打印的,在打印end之前等待了3秒,使得主程序阻塞了3秒,这时候给用户的体验就会很卡顿。阻塞的3秒对于后面主线程的代码执行并没有任何影响,实际项目中也许是开启了一些应用程序的其他附加服务。

下面我再用多任务模块处理一下阻塞代码。

2、多任务执行

  • 测试代码:
// main.js
...
console.info('start'); // 开启子任务
new Task('./task.js'); console.info('end');
...
// task.js
let t = 0;
while (t < 3000) {
console.warn('wait...');
sys.sleep(1000);
t += 1000;
}
  • 运行结果:



    在上面测试代码代码中我们将3秒的阻塞代码放在了新建的task.js文件中,在main.js中我们通过Task模块实例化了一个多任务实例,参数为task.js的文件地址,这时候运行代码我们可以看到end字段的打印并不受多任务实例中的阻塞代码影响,这样就不会对主线程运行造成不必要的阻塞。而在Node.js中可以通过异步I/O交给内部线程池、工作线程或者开启子进程进行处理。

数据通信

我们都知道线程之间是并行运行的,一个线程是无法直接访问其他线程内部数据的,按照官网的说法,每一个多任务就是一个线程,那多任务之间的数据应该也是各自维护,隔离开的。那么多任务之间如何能工进行数据通信呢?这边在爱智开发手册上看到有很多中方式去进行多任务间通信。其中有个比较有特点的是一个叫SyncTable的共享映射数据库,该模块具体的作用个人感觉应该是js模块间通信(纯属个人意见,错了勿喷!)。

说岔了,言归正传!我们看一下这边多任务的通信方式之一:信号槽通信(SigSlot)。

据官网介绍:

SigSlot 是一个事件驱动的异步通信组件,支持多任务和多进程。如果您需要多进程支持,则必须启动 JSRE(全局信号槽)并-g在启动进程时使用选项启用当前进程 GSS 支持。在 EdgerOS 中,来自同一供应商的应用程序可以使用 GSS 功能相互订阅和发布消息。

SigSlot是典型的订阅和发布通信机制。基于 SigSlot,可以轻松进行多任务解耦。每个任务都是独立设计的,大大降低了应用开发的难度。

下面直接来使用一下这个模块:

  • 测试代码

    // main.js
    ... const SigSlot = require('sigslot');
    const testSlot = new SigSlot('test');
    testSlot.slot('task', (msg) => {
    console.log('main: ', msg);
    testSlot.emit('main', 'main to task');
    }) new Task('./task.js');
    ...
    // task.js
    
    const SigSlot = require('sigslot');
    const testSlot = new SigSlot('test');
    testSlot.slot('main', (msg) => {
    console.log('task: ', msg);
    }) testSlot.emit('task', 'task to main'); require('iosched').forever();
  • 运行结果:



    从运行结果中可以看到在JSRE中,多任务之间可以通过信号槽进行数据的相互传递,意味着多任务是可以进行数据通信的,主要依赖于发布订阅模式来实现模块间通信的功能。

其实,最开始结果是只打印了main.js订阅的task事件,而mian.js中发布的main事件在task.js中并没有进行打印,一头雾水的我对照官网用法检查了好几遍,没发现写法有什么错误,写法问题就直接排除了。定位到应该是事件处理没有触发。

这时候我注意到了这个iosched这个模块,经过一番查找,终于知道了原因。

该模块为JSRE的核心模块之一,简单理解为就是处理异步I/0事件调度。

如果想要是js模块始终执行异步事件循环,可以显示调用该模块的forever方法去实现(require('iosched').forever()),这点和Node.js有着很大的差异,为什么JSRE要这样处理?可惜这个不是今天的重点,后面也会去介绍一下该模块。

多任务总结

关于JSRE中的多任务模块个人感觉还是很不错的,

首先是这种多任务的写法,比较直观,个人比较推荐的;

其次就是多任务可控,JSRE针对该模块还提供了很多的其他的接口供开发者进行任务控制。



​ 上图就是个人从使用上最直观的感受,至于底层多任务的实现以及JSRE本身是不是多线程机制或许只有等开源后方可知晓。这次就扯到这里就可以了,上面关于JSRE的异步事件循环机制和Node.js内置的事件循环有什么异同,下次将会为大家通过对比进行讲解。

如果以上有说的不对的,欢迎下面评论。

JSRE中的多任务与多线程的更多相关文章

  1. 聊聊Python中的多进程和多线程

    今天,想谈一下Python中的进程和线程. 最近在学习Django的时候,涉及到了多进程和多线程的知识点,所以想着一下把Python中的这块知识进行总结,所以系统地学习了一遍,将知识梳理如下. 1. ...

  2. ios7中的多任务

    转自:http://onevcat.com/2013/08/ios7-background-multitask/ WWDC 2013 Session笔记 - iOS7中的多任务 iOS7的后台多任务特 ...

  3. Linux中查看进程的多线程pstree, ps -L

    Linux中查看进程的多线程 在SMP系统中,我们的应用程序经常使用多线程的技术,那么在Linux中如何查看某个进程的多个线程呢? 本文介绍3种命令来查看Linux系统中的线程(LWP)的情况:在我的 ...

  4. PHP中实现异步调用多线程程序代码

    本文章详细的介绍了关于PHP中实现异步调用多线程方法,下面我们以给1000个用户发送一封推荐邮件,用户输入或者导入邮件账号了提交服务器执行发送来讲述. 比如现在有一个场景,给1000个用户发送一封推荐 ...

  5. [ios-必看] WWDC 2013 Session笔记 - iOS7中的多任务【转】

    感谢:http://onevcat.com/2013/08/ios7-background-multitask/ http://www.objc.io/issue-5/multitasking.htm ...

  6. Java中使用CountDownLatch进行多线程同步

    CountDownLatch介绍 在前面的Java学习笔记中,总结了Java中进行多线程同步的几个方法: 1.synchronized关键字进行同步. 2.Lock锁接口及其实现类ReentrantL ...

  7. 第九节:详细讲解Java中的泛型,多线程,网络编程

    前言 大家好,给大家带来详细讲解Java中的泛型,多线程,网络编程的概述,希望你们喜欢 泛型 泛型格式:ArrayList list= new ArrayList(); ArrayList list= ...

  8. iOS7中的多任务 - Background Fetch,Silent Remote Notifications,Background Transfer Service

    转自:http://onevcat.com/2013/08/ios7-background-multitask/ 在IOS 7 出来不就,公司内部也组织了一次关于IOS 7 特性的的分享,今天看见on ...

  9. 深入浅析python中的多进程、多线程、协程

    深入浅析python中的多进程.多线程.协程 我们都知道计算机是由硬件和软件组成的.硬件中的CPU是计算机的核心,它承担计算机的所有任务. 操作系统是运行在硬件之上的软件,是计算机的管理者,它负责资源 ...

随机推荐

  1. Java基础之(十二):数组

    数组 数组概述 定义 数组是相同类型数据的有序集合. 数组描述的是相同类型的若干数据,按照一定的先后次序排列组合而成. 其中,每一个数据称作一个数组元素,每个数组元素可以通过一个下标来访问它们. 数组 ...

  2. C 可变参数列表 stdarg.h

    内容来自<c和指针>,整理后方便个人理解 stdarg.h 菜鸟教程 - <stdarg.h> 类型 va_list 宏 va_start va_arg va_end #inc ...

  3. LeetCode:堆专题

    堆专题 参考了力扣加加对与堆专题的讲解,刷了些 leetcode 题,在此做一些记录,不然没几天就忘光光了 力扣加加-堆专题(上) 力扣加加-堆专题(下) 总结 优先队列 // 1.java中有优先队 ...

  4. [对对子队]会议记录4.12(Scrum Meeting 3)

    今天已完成的工作 朱骏豪 ​ 工作内容:找到了游戏的背景场景,用PS扣了按钮的图 ​ 相关issue:实现UI的美术需求 实现游戏场景中的必要模型 梁河览 ​ 工作内容:将关卡选择界面和欢迎界面导入项 ...

  5. OO2020 助教工作总结

    1 我的初衷 这一学期的OO助教工作是我一段宝贵的经历,在其中我学习了很多.见识了很多,收获满满.当时报名OO的初衷主要有三方面.首先,我想说OO是我所上过的最好的一门课之一,这门课有这一套从理论讲授 ...

  6. 手把手教你学Dapr - 2. 必须知道的概念

    Sidecar 边车 Dapr API提供Http和gRPC两种通讯方式. 运行方式则可以是容器也可以是进程(Windows开发推荐使用Self Hosted,后续会解释). 这样的好处是与运行环境无 ...

  7. git为单独的仓库设置提交的用户名

    在我们平时的学习中可能有这么一种需求,在公司进行开发的时候,一般会参与多个项目的开发,而项目提交代码时,一般请求情况下提供的用户都是同一个,而我们为了方便可能会使用全局进行git 用户名的配置.但是空 ...

  8. Noip模拟74 2021.10.11

    T1 自然数 考场上当我发现我的做法可能要打线段树的时候,以为自己百分之百是考虑麻烦了 但还是打了,还过掉了所有的样例,于是十分自信的就交了 正解还真是线段树,真就第一题数据结构 但是包括自己造的小样 ...

  9. HDI PCB一阶和二阶和三阶如何区分??

      一阶板,一次压合即成,可以想像成最普通的板二阶板,两次压合,以盲埋孔的八层板为例,先做2-7层的板,压好,这时候2-7的通孔埋孔已经做好了,再加1层和8层压上去,打1-8的通孔,做成整板.三阶板就 ...

  10. ASP.NET WEBAPI 跨域请求 405错误

    浏览器报错 本来没有报这个错,当我在ajax中添加了请求头信息时报错 405的报错大概就是后端程序没有允许此次请求,要解决这个问题,就是在后端程序中允许请求通过.具体操作就是修改web.config配 ...