harmony 鸿蒙Synchronous Task Development

  • 2023-10-30
  • 浏览 (485)

Synchronous Task Development

Synchronous tasks are executed in order among multiple threads. For example, as a synchronization primitive, locks prevent data contention.

To implement synchronous tasks, you must consider the collaboration and synchronization between multiple threads and ensure the correctness of data and the correct execution of programs.

If synchronous tasks are independent of each other, you are advised to use TaskPool, since it focuses on single independent tasks. For example, a series of imported static methods or methods implemented in singletons are independent. If synchronous tasks are associated with each other, use Worker, for example, methods implemented in class objects (not singleton class objects).

Using TaskPool to Process Independent Synchronous Tasks

TaskPool is recommended for scheduling independent synchronous tasks. Typical synchronous tasks are those using static methods. If a unique handle or class object constructed using a singleton points to multiple tasks and these tasks can be used between different worker threads, you can also use TaskPool.

  1. Define a concurrency function that internally calls the synchronous methods.

  2. Create a task, execute the task through TaskPool, and perform operations on the asynchronous result. Create a task and call execute() to execute the task synchronously.

  3. Perform concurrent operations.

Simulate a singleton class that contains synchronous calls.

// handle.ts code
export default class Handle {
  static getInstance(): void {
    // Return a singleton object.
  }

  static syncGet(): void {
    // Synchronous getter.
  }

  static syncSet(num: number): void {
    // Synchronous setter.
  }
}

Use TaskPool to call the related synchronous methods.

// Index.ets code
import taskpool from '@ohos.taskpool';
import Handle from './Handle'; // Return a static handle.

// Step 1: Define a concurrency function that internally calls the synchronous methods.
@Concurrent
function func(num: number): boolean {
  // Call the synchronous wait implemented in a static class object.
  Handle.syncSet(num);
  return true;
}

// Step 2: Create and execute a task.
async function asyncGet(): Promise<void> {
  // Create a task and pass in the function func.
  let task: taskpool.Task = new taskpool.Task(func, 1);
  // Execute the task and perform operations on the result after the synchronization logic is executed.
  console.info(String(await taskpool.execute(task)));
}

@Entry
@Component
struct Index {
  @State message: string = 'Hello World';

  build() {
    Row() {
      Column() {
        Text(this.message)
          .fontSize(50)
          .fontWeight(FontWeight.Bold)
          .onClick(() => {
            // Step 3: Perform concurrent operations.
            asyncGet();
          })
      }
      .width('100%')
      .height('100%')
    }
  }
}

Using Worker to Process Associated Synchronous Tasks

Use Worker when you want to schedule a series of synchronous tasks using the same handle or depending on the same class object.

  1. Create a Worker object in the main thread and receive messages from the worker thread.

    import worker from '@ohos.worker';
    
    
    @Entry
    @Component
    struct Index {
      @State message: string = 'Hello World';
    
    
      build() {
        Row() {
          Column() {
            Text(this.message)
              .fontSize(50)
              .fontWeight(FontWeight.Bold)
              .onClick(() => {
                let w: worker.ThreadWorker = new worker.ThreadWorker('entry/ets/workers/MyWorker.ts');
                w.onmessage = (): void => {
                  // Receive the result of the worker thread.
                }
                w.onerror = (): void => {
                  // Receive error information of the worker thread.
                }
                // Send a Set message to the worker thread.
                w.postMessage({'type': 0, 'data': 'data'})
                // Send a Get message to the worker thread.
                w.postMessage({'type': 1})
                // Destroy the worker thread.
                w.terminate()
              })
          }
          .width('100%')
        }
        .height('100%')
      }
    }
    
  2. Bind the Worker object in the worker thread and process the synchronous task logic.

    // handle.ts code
    export default class Handle {
      syncGet() {
        return;
      }
    
    
      syncSet(num: number) {
        return;
      }
    }
    
    // Worker.ts code
    import worker, { ThreadWorkerGlobalScope, MessageEvents } from '@ohos.worker';
    import Handle from './handle'  // Return a handle.
    
    
    let workerPort : ThreadWorkerGlobalScope = worker.workerPort;
    
    
    // Handle that cannot be transferred. All operations depend on this handle.
    let handler: Handle = new Handle()
    
    
    // onmessage() logic of the worker thread.
    workerPort.onmessage = (e : MessageEvents): void => {
     switch (e.data.type as number) {
      case 0:
       handler.syncSet(e.data.data);
       workerPort.postMessage('success set');
      case 1:
       handler.syncGet();
       workerPort.postMessage('success get');
     }
    }
    

你可能感兴趣的鸿蒙文章

harmony 鸿蒙ArkTS Common Library

harmony 鸿蒙Comparison Between the Actor and Memory Sharing Models

harmony 鸿蒙Overview of ArkTS Common Library

harmony 鸿蒙Asynchronous Concurrency Overview

harmony 鸿蒙Concurrency Overview

harmony 鸿蒙Overview of Containers

harmony 鸿蒙CPU Intensive Task Development

harmony 鸿蒙I/O Intensive Task Development

harmony 鸿蒙Linear Containers

harmony 鸿蒙Multithread Concurrency Overview

0  赞