实现多Worker并进行调用传递消息,利用registerGlobalCallObject传递对象及调用函数,获取buffer,注:callGlobalCallObjectMethod方法在主线程中运行。
- Index.ets文件中,调用自定义函数。
import { testMultyWorker } from './testWorker'; // 导入方法
@Entry
@Component
struct Index {
build() {
Row() {
Column() {
Button('test workers')
.onClick(() => {
testMultyWorker(); // 测试多worker
})
}.width('100%')
}.height('100%')
}
}
- TestWorker.ets文件中实现worker管理调度。
import { MessageEvents, worker } from '@kit.ArkTS';
const mainThreadTag: string = 'mainthread';
// 初始化2个worker,如果close或者terminate就不能用了
let worker1: worker.ThreadWorker = new worker.ThreadWorker('entry/ets/workers/worker1.ets', { name: 'worker1' });
let worker2: worker.ThreadWorker = new worker.ThreadWorker('entry/ets/workers/worker2.ets', { name: 'worker2' });
// 自定义单例
class TestObj {
private message: string = 'this is a message from TestObj';
public getMessage(): string {
console.log(mainThreadTag, 'worker call obj func: getMessage()');
return this.message;
}
public getMessageWithInput(str: string): string {
return this.message + 'with input:' + str;
}
public setSharedArrayBuffer() {
let num = new Int16Array(this.sharedBuffer);
num[0] = 20;
}
public getSharedArrayBuffer(): SharedArrayBuffer {
return this.sharedBuffer;
}
static registerObj: TestObj = new TestObj();
private sharedBuffer: SharedArrayBuffer = new SharedArrayBuffer(1024);
}
// worker 的otnMessage 监听
function onMessage(e: MessageEvents): void {
switch (e.data.type as number) {
case 0:
console.log(mainThreadTag, 'received message type: 0, value is: %{public}s, next to post msg to worker2',
e.data.value);
worker2.postMessage('This is msg from mainthread switch');
break;
case 1:
console.log(mainThreadTag, 'received message value %{public}d, next to post msg to worker1',
e.data.value as number);
worker1.postMessage({ 'type': 0 });
break;
default:
console.log(mainThreadTag, 'invalid type, next to return');
// 增加一个定时,体现worker运行
setTimeout(() => {
console.log(mainThreadTag, 'invalid type, next to return');
}, 5000);
break;
}
}
// export 函数
export function testMultyWorker() {
TestObj.registerObj.setSharedArrayBuffer();
// 在ThreadWorker实例上注册registerObj
worker2.registerGlobalCallObject('myObj', TestObj.registerObj);
worker1.registerGlobalCallObject('myObj', TestObj.registerObj);
console.log(mainThreadTag, 'this is a msg to start worker');
worker1.postMessage('this is a msg to start worker1');
worker1.onmessage = onMessage;
worker2.onmessage = onMessage;
console.log(mainThreadTag, 'end');
worker1.onexit = () => {
console.log('main thread terminate worker1');
}
worker2.onexit = () => {
console.log('main thread terminate worker2');
}
}
-
Worker代码如下:
Worker1.ets:
import { ErrorEvent, MessageEvents, ThreadWorkerGlobalScope, worker, process } from '@kit.ArkTS';
const worker1: string = 'worker1';
const workerPort: ThreadWorkerGlobalScope = worker.workerPort;
workerPort.onmessage = (e: MessageEvents) => {
console.log(worker1, 'enter worker1, process uid:%{public}d, pid:%{public}d, tid:%{public}d',
process.uid, process.pid, process.tid);
if (e.data.type === 0) {
workerPort.postMessage({ 'type': 2 });
console.log(worker1, 'begin to end worker1');
// workerPort.close() // close后不允许再使用,否则引发crash
return;
}
try {
let str1: string = workerPort.callGlobalCallObjectMethod('myObj', 'getMessage', 0) as string;
console.log(worker1, 'call shared class to get func: getMessage(), return is: %{public}s', str1);
} catch (e) {
console.log(worker1, 'call shared class getMessage get this %{public}s ,errcode %{public}d', e.message, e.code);
}
try {
let res: SharedArrayBuffer =
workerPort.callGlobalCallObjectMethod('myObj', 'getSharedArrayBuffer', 0) as SharedArrayBuffer;
let typedArr = new Int16Array(res);
console.log(worker1, 'call shared class func: getSharedArrayBuffer(), return is: %{public}d', typedArr[0]);
typedArr[0] = 25;
console.log(worker1, 'work1 change the value to: %{public}d', typedArr[0]);
} catch (e) {
console.log(worker1, 'call shared class getSharedArrayBuffer get this %{public}s', e.message);
}
workerPort.postMessage({ 'type': 0, 'value': 'this is a msg from worker1 to main' });
}
workerPort.onmessageerror = (e: MessageEvents) => {
console.log(worker1, 'received a message error');
}
workerPort.onerror = (e: ErrorEvent) => {
console.log(worker1, 'worker1 error');
}
Worker2.ets:
import { ErrorEvent, MessageEvents, ThreadWorkerGlobalScope, worker, process } from '@kit.ArkTS';
const worker2: string = 'worker2=
const workerPort: ThreadWorkerGlobalScope = worker.workerPort;
workerPort.onmessage = (e: MessageEvents) => {
console.log(worker2, 'enter worker2, process update %{public}d,%{public}d,%{public}d', process.uid, process.pid,
process.tid);
let str: string = workerPort.callGlobalCallObjectMethod('myObj', 'getMessage', 0) as string;
console.log(worker2, 'call shared class func get value: %{public}s', str);
let res: SharedArrayBuffer =
workerPort.callGlobalCallObjectMethod('myObj', 'getSharedArrayBuffer', 0) as SharedArrayBuffer;
let typedArr = new Int16Array(res);
console.log(worker2, 'call shared class func get value: %{public}d', typedArr[0]);
workerPort.postMessage({ 'type': 1, 'value': typedArr[0] });
}
workerPort.onmessageerror = (e: MessageEvents) => {
console.log(worker2, 'received a message error');
}
workerPort.onerror = (e: ErrorEvent) => {
console.log(worker2, 'worker2 error');
}