1e41f4b71Sopenharmony_ci# CPU Intensive Task Development (TaskPool and Worker) 2e41f4b71Sopenharmony_ci 3e41f4b71Sopenharmony_ci 4e41f4b71Sopenharmony_ciCPU intensive tasks are tasks that occupy a significant amount of system computing resources and that may block other tasks in the same thread. Example CPU intensive tasks are image processing, video encoding, and data analysis. 5e41f4b71Sopenharmony_ci 6e41f4b71Sopenharmony_ci 7e41f4b71Sopenharmony_ciTo improve CPU utilization and application response speeds, use multithread concurrency in processing CPU intensive tasks. 8e41f4b71Sopenharmony_ci 9e41f4b71Sopenharmony_ci 10e41f4b71Sopenharmony_ciIf a task can be completed in a background thread within 3 minutes, you are advised to use TaskPool. Otherwise, use Worker. The following uses histogram processing and a time-consuming model prediction task in the background as examples. 11e41f4b71Sopenharmony_ci 12e41f4b71Sopenharmony_ci 13e41f4b71Sopenharmony_ci## Using TaskPool to Process Histograms 14e41f4b71Sopenharmony_ci 15e41f4b71Sopenharmony_ci1. Implement the logic of image processing. 16e41f4b71Sopenharmony_ci 17e41f4b71Sopenharmony_ci2. Segment the data, and initiate associated task scheduling through task groups. 18e41f4b71Sopenharmony_ci 19e41f4b71Sopenharmony_ci Create a [task group](../reference/apis-arkts/js-apis-taskpool.md#taskgroup10), call [addTask()](../reference/apis-arkts/js-apis-taskpool.md#addtask10) to add tasks, and call [execute()](../reference/apis-arkts/js-apis-taskpool.md#taskpoolexecute10) to execute the tasks in the task group at a [a high priority](../reference/apis-arkts/js-apis-taskpool.md#priority). After all the tasks in the task group are complete, the histogram processing result is returned simultaneously. 20e41f4b71Sopenharmony_ci 21e41f4b71Sopenharmony_ci3. Summarize and process the result arrays. 22e41f4b71Sopenharmony_ci 23e41f4b71Sopenharmony_ci```ts 24e41f4b71Sopenharmony_ciimport { taskpool } from '@kit.ArkTS'; 25e41f4b71Sopenharmony_ci 26e41f4b71Sopenharmony_ci@Concurrent 27e41f4b71Sopenharmony_cifunction imageProcessing(dataSlice: ArrayBuffer): ArrayBuffer { 28e41f4b71Sopenharmony_ci // Step 1: Perform specific image processing operations and other time-consuming operations. 29e41f4b71Sopenharmony_ci return dataSlice; 30e41f4b71Sopenharmony_ci} 31e41f4b71Sopenharmony_ci 32e41f4b71Sopenharmony_cifunction histogramStatistic(pixelBuffer: ArrayBuffer): void { 33e41f4b71Sopenharmony_ci // Step 2: Perform concurrent scheduling for data in three segments. 34e41f4b71Sopenharmony_ci let number: number = pixelBuffer.byteLength / 3; 35e41f4b71Sopenharmony_ci let buffer1: ArrayBuffer = pixelBuffer.slice(0, number); 36e41f4b71Sopenharmony_ci let buffer2: ArrayBuffer = pixelBuffer.slice(number, number * 2); 37e41f4b71Sopenharmony_ci let buffer3: ArrayBuffer = pixelBuffer.slice(number * 2); 38e41f4b71Sopenharmony_ci 39e41f4b71Sopenharmony_ci let group: taskpool.TaskGroup = new taskpool.TaskGroup(); 40e41f4b71Sopenharmony_ci group.addTask(imageProcessing, buffer1); 41e41f4b71Sopenharmony_ci group.addTask(imageProcessing, buffer2); 42e41f4b71Sopenharmony_ci group.addTask(imageProcessing, buffer3); 43e41f4b71Sopenharmony_ci 44e41f4b71Sopenharmony_ci taskpool.execute(group, taskpool.Priority.HIGH).then((ret: Object) => { 45e41f4b71Sopenharmony_ci // Step 3: Summarize and process the result arrays. 46e41f4b71Sopenharmony_ci }) 47e41f4b71Sopenharmony_ci} 48e41f4b71Sopenharmony_ci 49e41f4b71Sopenharmony_ci@Entry 50e41f4b71Sopenharmony_ci@Component 51e41f4b71Sopenharmony_cistruct Index { 52e41f4b71Sopenharmony_ci @State message: string = 'Hello World' 53e41f4b71Sopenharmony_ci 54e41f4b71Sopenharmony_ci build() { 55e41f4b71Sopenharmony_ci Row() { 56e41f4b71Sopenharmony_ci Column() { 57e41f4b71Sopenharmony_ci Text(this.message) 58e41f4b71Sopenharmony_ci .fontSize(50) 59e41f4b71Sopenharmony_ci .fontWeight(FontWeight.Bold) 60e41f4b71Sopenharmony_ci .onClick(() => { 61e41f4b71Sopenharmony_ci let buffer: ArrayBuffer = new ArrayBuffer(24); 62e41f4b71Sopenharmony_ci histogramStatistic(buffer); 63e41f4b71Sopenharmony_ci }) 64e41f4b71Sopenharmony_ci } 65e41f4b71Sopenharmony_ci .width('100%') 66e41f4b71Sopenharmony_ci } 67e41f4b71Sopenharmony_ci .height('100%') 68e41f4b71Sopenharmony_ci } 69e41f4b71Sopenharmony_ci} 70e41f4b71Sopenharmony_ci``` 71e41f4b71Sopenharmony_ci 72e41f4b71Sopenharmony_ci 73e41f4b71Sopenharmony_ci## Using Worker for Time-Consuming Model Prediction 74e41f4b71Sopenharmony_ci 75e41f4b71Sopenharmony_ciThe following uses the training of a region-specific house price prediction model as an example. This model can be used to predict house prices in the region based on the house area and number of rooms. The model needs to run for a long time, and each prediction needs to use the previous running result. Due to these considerations, Worker is used for the development. 76e41f4b71Sopenharmony_ci 77e41f4b71Sopenharmony_ci1. In DevEco Studio, add a worker named **MyWorker** to your project. 78e41f4b71Sopenharmony_ci 79e41f4b71Sopenharmony_ci  80e41f4b71Sopenharmony_ci 81e41f4b71Sopenharmony_ci2. In the main thread, call [constructor()](../reference/apis-arkts/js-apis-worker.md#constructor9) of **ThreadWorker** to create a **Worker** object. The calling thread is the host thread. 82e41f4b71Sopenharmony_ci 83e41f4b71Sopenharmony_ci ```ts 84e41f4b71Sopenharmony_ci // Index.ets 85e41f4b71Sopenharmony_ci import { worker } from '@kit.ArkTS'; 86e41f4b71Sopenharmony_ci 87e41f4b71Sopenharmony_ci const workerInstance: worker.ThreadWorker = new worker.ThreadWorker('entry/ets/workers/MyWorker.ts'); 88e41f4b71Sopenharmony_ci ``` 89e41f4b71Sopenharmony_ci 90e41f4b71Sopenharmony_ci3. In the host thread, call [onmessage()](../reference/apis-arkts/js-apis-worker.md#onmessage9) to receive messages from the worker thread, and call [postMessage()](../reference/apis-arkts/js-apis-worker.md#postmessage9) to send messages to the worker thread. 91e41f4b71Sopenharmony_ci 92e41f4b71Sopenharmony_ci For example, the host thread sends training and prediction messages to the worker thread, and receives messages sent back by the worker thread. 93e41f4b71Sopenharmony_ci 94e41f4b71Sopenharmony_ci ```ts 95e41f4b71Sopenharmony_ci // Index.ets 96e41f4b71Sopenharmony_ci let done = false; 97e41f4b71Sopenharmony_ci 98e41f4b71Sopenharmony_ci // Receive the result from the worker thread. 99e41f4b71Sopenharmony_ci workerInstance.onmessage = (() => { 100e41f4b71Sopenharmony_ci console.info('MyWorker.ts onmessage'); 101e41f4b71Sopenharmony_ci if (!done) { 102e41f4b71Sopenharmony_ci workerInstance.postMessage({ 'type': 1, 'value': 0 }); 103e41f4b71Sopenharmony_ci done = true; 104e41f4b71Sopenharmony_ci } 105e41f4b71Sopenharmony_ci }) 106e41f4b71Sopenharmony_ci 107e41f4b71Sopenharmony_ci workerInstance.onerror = (() => { 108e41f4b71Sopenharmony_ci // Receive error information from the worker thread. 109e41f4b71Sopenharmony_ci }) 110e41f4b71Sopenharmony_ci 111e41f4b71Sopenharmony_ci // Send a training message to the worker thread. 112e41f4b71Sopenharmony_ci workerInstance.postMessage({ 'type': 0 }); 113e41f4b71Sopenharmony_ci ``` 114e41f4b71Sopenharmony_ci 115e41f4b71Sopenharmony_ci4. Bind the **Worker** object in the **MyWorker.ts** file. The calling thread is the worker thread. 116e41f4b71Sopenharmony_ci 117e41f4b71Sopenharmony_ci ```ts 118e41f4b71Sopenharmony_ci // MyWorker.ts 119e41f4b71Sopenharmony_ci import { worker, ThreadWorkerGlobalScope, MessageEvents, ErrorEvent } from '@kit.ArkTS'; 120e41f4b71Sopenharmony_ci 121e41f4b71Sopenharmony_ci let workerPort: ThreadWorkerGlobalScope = worker.workerPort; 122e41f4b71Sopenharmony_ci ``` 123e41f4b71Sopenharmony_ci 124e41f4b71Sopenharmony_ci5. In the worker thread, call [onmessage()](../reference/apis-arkts/js-apis-worker.md#onmessage9-1) to receive messages sent by the host thread, and call [postMessage()](../reference/apis-arkts/js-apis-worker.md#postmessage9-2) to send messages to the host thread. 125e41f4b71Sopenharmony_ci 126e41f4b71Sopenharmony_ci For example, the prediction model and its training process are defined in the worker thread, and messages are exchanged with the main thread. 127e41f4b71Sopenharmony_ci 128e41f4b71Sopenharmony_ci ```ts 129e41f4b71Sopenharmony_ci // MyWorker.ts 130e41f4b71Sopenharmony_ci // Define the training model and result. 131e41f4b71Sopenharmony_ci let result: Array<number>; 132e41f4b71Sopenharmony_ci // Define the prediction function. 133e41f4b71Sopenharmony_ci function predict(x: number): number { 134e41f4b71Sopenharmony_ci return result[x]; 135e41f4b71Sopenharmony_ci } 136e41f4b71Sopenharmony_ci // Define the optimizer training process. 137e41f4b71Sopenharmony_ci function optimize(): void { 138e41f4b71Sopenharmony_ci result = [0]; 139e41f4b71Sopenharmony_ci } 140e41f4b71Sopenharmony_ci // onmessage logic of the worker thread. 141e41f4b71Sopenharmony_ci workerPort.onmessage = (e: MessageEvents): void => { 142e41f4b71Sopenharmony_ci // Perform operations based on the type of data to transmit. 143e41f4b71Sopenharmony_ci switch (e.data.type as number) { 144e41f4b71Sopenharmony_ci case 0: 145e41f4b71Sopenharmony_ci // Perform training. 146e41f4b71Sopenharmony_ci optimize(); 147e41f4b71Sopenharmony_ci // Send a training success message to the main thread after training is complete. 148e41f4b71Sopenharmony_ci workerPort.postMessage({ type: 'message', value: 'train success.' }); 149e41f4b71Sopenharmony_ci break; 150e41f4b71Sopenharmony_ci case 1: 151e41f4b71Sopenharmony_ci // Execute the prediction. 152e41f4b71Sopenharmony_ci const output: number = predict(e.data.value as number); 153e41f4b71Sopenharmony_ci // Send the prediction result to the main thread. 154e41f4b71Sopenharmony_ci workerPort.postMessage({ type: 'predict', value: output }); 155e41f4b71Sopenharmony_ci break; 156e41f4b71Sopenharmony_ci default: 157e41f4b71Sopenharmony_ci workerPort.postMessage({ type: 'message', value: 'send message is invalid' }); 158e41f4b71Sopenharmony_ci break; 159e41f4b71Sopenharmony_ci } 160e41f4b71Sopenharmony_ci } 161e41f4b71Sopenharmony_ci ``` 162e41f4b71Sopenharmony_ci 163e41f4b71Sopenharmony_ci6. After the task is completed in the worker thread, destroy the worker thread. The worker thread can be destroyed by itself or the host thread. Then, call [onexit()](../reference/apis-arkts/js-apis-worker.md#onexit9) in the host thread to define the processing logic after the worker thread is destroyed. 164e41f4b71Sopenharmony_ci 165e41f4b71Sopenharmony_ci ```ts 166e41f4b71Sopenharmony_ci // After the worker thread is destroyed, execute the onexit() callback. 167e41f4b71Sopenharmony_ci workerInstance.onexit = (): void => { 168e41f4b71Sopenharmony_ci console.info("main thread terminate"); 169e41f4b71Sopenharmony_ci } 170e41f4b71Sopenharmony_ci ``` 171e41f4b71Sopenharmony_ci 172e41f4b71Sopenharmony_ci Method 1: In the host thread, call [terminate()](../reference/apis-arkts/js-apis-worker.md#terminate9) to destroy the worker thread and stop the worker thread from receiving messages. 173e41f4b71Sopenharmony_ci 174e41f4b71Sopenharmony_ci ```ts 175e41f4b71Sopenharmony_ci // Destroy the worker thread. 176e41f4b71Sopenharmony_ci workerInstance.terminate(); 177e41f4b71Sopenharmony_ci ``` 178e41f4b71Sopenharmony_ci 179e41f4b71Sopenharmony_ci Method 2: In the worker thread, call [close()](../reference/apis-arkts/js-apis-worker.md#close9) to destroy the worker thread and stop the worker thread from receiving messages. 180e41f4b71Sopenharmony_ci 181e41f4b71Sopenharmony_ci ```ts 182e41f4b71Sopenharmony_ci // Destroy the worker thread. 183e41f4b71Sopenharmony_ci workerPort.close(); 184e41f4b71Sopenharmony_ci ``` 185