11RIA 闪客社区 - 最赞 Animate Flash 论坛

搜索
查看: 3062|回复: 4
上一主题 下一主题

[AIR 开发] 【AS3 Worker(多线程)探秘 1】———理解和看法,AS3中多线程的设计

[复制链接] TA的其它主题
发表于 2018-11-5 10:47:45 | 显示全部楼层 |阅读模式

【游客模式】——注册会员,加入11RIA 闪客社区吧!一起见证Flash的再次辉煌……

您需要 登录 才可以下载或查看,没有帐号?立即注册

x
本帖最后由 TKCB 于 2020-2-21 07:59 编辑

TKCB网站
网址:www.tkcb.cc


【AS3多线程探秘】——系列教程,共五篇
目录


Worker?Why?
如何开始呢?那么我就先说说我对AS3里面多线程的理解和看法吧。

1. 多线程是为了保证电脑运行不卡和速度更快
首先,多线程大家知道,可以通过线程的方式同时运行多个代码块,以保证在复杂计算时候程序的稳定运行(画面不卡等),如果把任务分块交给多个线程则可以保证速度更快(前提是有多个处理器)。

2. AS3中最好只使用一个或者两个线程
然而,AS3的多线程可能不像其他语言那么好用(我猜的),AS3的多线程的大致思路就是,在Flash Player中每一个线程都有一个独立的AVM2虚拟机(原本只有两个虚拟机,一个AVM1用于运行AS2.0的东西,一个AVM2用于运行3.0的东西),也就是每创建一个线程(Worker)就会多创建一个AVM2,所以Adobe官方也建议大家在原来的基础上再使用一个或者两个线程(Worker)就好,多了会很吃电脑内存。

3. 多线程的两个概念并发和并行
多线程分为并发和并行。
并发是处理器在多个线程之间跳转执行代码。
并行是在多个处理器的时候可以多处理器同时运行不同的线程(真正的代码同时运行)。
虽然多线程应该是代码被设计成多部分同时进行,但实际对于多数程序或者AS来说,只需要一个子线程在代码运行比较卡的时候让程序不卡。

注意:在之后帖子的三个fla测试练习中,我对AS3并发和并行的理解可能有些错误,因为我在官方的API中看到了并行这个词,我在想是否AS3已经实现了多处理器的时候的并行技术


AS3中多线程的设计
先来梳理一下,Adobe是如何设计AS3的多线程的。

AS3将多线程分为三部分:
一个是线程对象Worker,
一个是线程之间的通信(MessageChannel和其他的通信方法),
一个是创建和访问线程对象的机制WorkerDomain对象。

默认我们不创建多线程的情况,其实本身程序就运行着一个Worker(这个是原始的或者说是主的)。

下面我会将默认的Worker称之为主线程,而额外创建的Worker称之为子线程,因为AS3是并发,所以从程序设计的角度来说,AS的代码应该是都在主线程中,而额外的线程仅仅是在运行很复杂计算的时候使用,所以称之为子比较合理。

1. WorkerDomain对象
之所以先说这个,是因为要创建子线程(也就是额外的线程),必须使用WorkerDomain对象。

1.1 静态属性访问WorkerDomain
WorkerDomain不可以被new,只能通过静态属性 current 进行访问,唯一的实例对象。

1.2 判断是否支持多线程
使用静态属性 isSupported 可以判断是否支持并发。

1.3 使用 createWorker() 方法创建子线程
使用 createWorker() 方法可以创建额外的线程,也就是我们将使用它创建一个子线程对象Worker,必须通过SWF的字节数组才可以创建Worker,有三种常用的方式可以创建子线程(具体方法见API):
• 使用 [Embed] 元标记将 .swf 文件作为 ByteArray 嵌入在应用程序中;
• 使用 URLLoader 加载外部 SWF 文件(这是我推荐和使用的方式);
• 将单个 swf 同时用作原始 worker 和后台 worker。

2. Worker对象
这是最核心的对象,但其实也很简单,因为它的属性和方法并不多,也都很关键。

2.1 静态属性访问Worker
使用静态属性 current 可以访问包含当前代码的Worker,也就是在主线程中的代码可以通过这个属性访问到主线程的Worker对象实例,而子线程的代码可以通过这个属性访问到子线程的Worker对象实例。

2.2 判断是否为原始的Worker
使用 isPrimordial 属性确定当前获取的Worker是否为原始的Worker,也就是是否是主线程。

2.3 判断是否支持并发/并行(有疑惑)
使用 isSupported 属性判断是否支持并发/并行,我在官方API看到的是并行,但是我的一直理解是AS3只实现了并发。。但是这个不重要,如果实现了更好,没实现也没办法不是吗。

2.4 判断Worker的当前状态
使用 state 判断Worker的状态,有三种,一种是新的线程(什么代码都没有执行 WorkerState.NEW),一种是正在运行的线程(WorkerState.RUNNING),一种是被停止的线程(WorkerState.TERMINATED)。

2.5 启动和停止Worker
start() 和 terminate() 方法可以启动和停止Worker,原始的Worker我估计没法和自行调用启动和停止(我猜的,你们可以试验)。

2.6 还有几个方法是跟通信机制有关的,所以在下面讲

3. 线程Worker之间的通信机制
线程与线程之间是完全的独立运行,所以当一个子线程完成了任务,就要把任务结果返回给主线程,于是就需要一个通信机制了。AS3的Worker有三种通信机制,用来发送消息和传送数据:
• 共享属性
• MessageChannel
• 可共享 ByteArray

3.1 共享属性
[官方介绍]
每个 worker 都有可以从该 worker 自身及其他 worker 设置和读取的一组内部命名值。您可以使用 setSharedProperty() 方法来设置值并使用 getSharedProperty() 方法来读取值
[TKCB]
其实就是当创建了子线程对象Worker后,使用这个子worker.setSharedProperty() 方法给里面设置传入数据对象,有两个参数一个是传入参数的名称字符串,用于之后的get方法获取,另一个是对象参数。
在子线程的代码中,可以使用Worker.current.getSharedProperty() 方法获取这个主线程里面传入的数据对象,通过set设置的名称字符串获取。
但是这个机制通常只用于,在子线程Worker还没启动的时候,传递下面的机制的对象 MessageChannel 给子线程。
因为使用这个set和get不能进行侦听,所以子线程就必须创建一个无线的Timer对象进行不断地get数据对象,所以很不方便。

3.2 MessageChannel
[官方介绍]
MessageChannel 对象允许您将单向消息和数据从一个 worker 发送到另一个 worker。接收 worker 中的代码可以侦听当有消息到达时要通知的事件。要创建 MessageChannel 对象,请使用 createMessageChannel() 方法。
[TKCB]
这是一个用于连接两个进程的通道对象,但它是单向的,也就是说如果想要主和子互通消息,必须创建两个这个对象(具体创建方式见API或者我的练习文件)。
使用上面提到的第一个通信机制将两个通道对象传入子线程中,这样子线程就可以侦听这两个对象,然后获取和发送消息和传送数据对象了。
这个是我推荐和使用的主要通信机制。

3.3 可共享 ByteArray
[官方介绍]
如果 ByteArray 对象的 shareable 属性为 true,则所有 worker 中该 ByteArray 的实例都使用相同的底层内存。由于多个 worker 中的代码可以同时访问共享内存,因此您的代码应使用 ByteArray.shareable 属性说明中描述的机制,以避免发生数据意外更改问题。
[TKCB]
如果子线程运算后的返回对象是ByteArray,则使用共享可以减少很多内存的消耗。


4. 最后总结一下
其实也挺简单,代码的主要基本结构应该是这样:
主线程:
•  判断是否支持子线程,
•  获取主线程对象,
•  创建子线程对象,
•  创建两个通信对象,
•  侦听子线程的通信对象(只侦听一个通信对象,根据侦听的结果运行其他代码),
•  给子线程传入通信对象,
•  启动子线程。

子线程:
•  获取子线程对象,
•  获取两个通信对象,
•  侦听两个线程的通信对象(因为子线程牵扯到收到消息和数据,然后运行代码计算,之后返回消息和数据),
•  根据侦听,然后运行不同的代码(或许是复杂的计算或者是返回消息和数据)。


参考资料和帖子
AS3多线程快速入门(一):Hello World[译]
(已失效)http://bbs.9ria.com/forum.php?mo ... 4587&fromuid=273124(已失效)

AS3多线程快速入门(二):图像处理[译]
(已失效)http://bbs.9ria.com/forum.php?mod=viewthread&tid=145065(已失效)

AS3并发机制的通俗解释
(已失效)http://bbs.9ria.com/thread-139324-1-1.html(已失效)

AS3.0多线程作用有多大?
(已失效)http://bbs.9ria.com/thread-147591-1-1.html(已失效)



听我说一些废话吧
多线程很不错,真好,虽然Adobe的多线程有一些地方会坑人,但至少实现了不是吗。


免费是最昂贵的
银子还是要收的,因为 “免费的东西最昂贵” ,请深刻理解这句话的含义!!!


广告
QQ(TKCB):2414268040(欢迎和我聊天交流,有朋自远方来不亦说乎)
QQ群:96759336(AS3殿堂之路,Flash Animate AS3 AIR 技术交流)
QQ群:705730359(H5天路历程,HTML5 CSS3 JaveScript  技术交流)
QQ群:463560360(King系列软件分享交流,TKCB 出品的 King 系列软件分享、使用、交流、反馈等)
TKCB网站:www.tkcb.cc
官方技术论坛:www.11ria.com

本帖被以下淘专辑推荐:

发表于 2019-3-22 09:56:20 | 显示全部楼层
大神,我最近一直在做多线程的学习。其中遇到一个问题,就是如果将主线程和子线程分别分配不同的内核上进行处理?
回复

使用道具 举报

 楼主| 发表于 2019-3-22 13:27:37 | 显示全部楼层
ganggang_lantia 发表于 2019-3-22 09:56
大神,我最近一直在做多线程的学习。其中遇到一个问题,就是如果将主线程和子线程分别分配不同的内核上进行 ...

Adobe没有提供这样的API~~或许你可以用ANE解决~
回复

使用道具 举报

发表于 2020-3-9 16:29:20 | 显示全部楼层
这些链接都失效了啊
回复

使用道具 举报

发表于 2020-3-10 10:35:00 | 显示全部楼层
ganggang_lantia 发表于 2019-3-22 09:56大神,我最近一直在做多线程的学习。其中遇到一个问题,就是如果将主线程和子线程分别分配不同的内核上进行 ...

这是自动的. 开多个worker线程时, 只要计算机有空闲核心资源, 会自动将worker分配到空闲的核心上运行

如双核电脑开4个worker, 则多出来的worker会自动分配到功耗压力较低的核心运行
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

关闭

站长推荐 上一条 /1 下一条

感谢所有支持论坛的朋友:下面展示最新的5位赞助和充值的朋友……更多赞助和充值朋友的信息,请查看:永远的感谢名单

SGlW(66139)、 anghuo(841)、 whdsyes(255)、 longxia(60904)、 囫囵吞澡(58054)

下面展示总排行榜的前3名(T1-T3)和今年排行榜的前3名的朋友(C1-C3)……更多信息,请查看:总排行榜今年排行榜

T1. fhqu1462(969)、 T2. lwlpluto(14232)、 T3. 1367926921(962)  |  C1. anghuo(147)、 C2. fdisker(27945)、 C3. 囫囵吞澡(58054)



快速回复 返回顶部 返回列表