鸿蒙并发能力TaskPool与内存共享并发模型对比

鸿蒙多线程并发

鸿蒙开发提供两种并发能力:TaskPool和Worker
两种能力都是基于Actor模型实现,是典型的内存不共享并发模型,每个线程都会创建独立的Actor,管理各自的独立内存,彼此之间通过通信机制实现数据交流

以经典的消费生产问题为例

内存共享模型下通过信号量PV操作模拟:

  • 生产者生成数据后,放在一个缓冲区
  • 消费者从缓冲区取出数据
  • 任何时刻只允许一个消费者或生产者访问缓冲区

说明

  • 操作缓冲区需要互斥
  • 缓冲区空时,消费者需要等待生产者生产,需要同步

需要三个信号量

  • 互斥信号量murex:用于访问缓冲区,初始化为1;
  • 资源信号量fullBuffers:用于消费者询问缓冲区是否有数据,有数据则读取,初始化为0(缓冲区一开始为空)
  • 资源信号量emptyBuffers:用于生产者询问缓冲区是否有空位,有空位则生成数据,初始化为n(缓冲区大小)
void Producer(){
    while(TRUE){
        P(emptyBuffers);//将空槽数量-1
        P(mutex);//进入临界区
        将生成的数据放入缓冲区;
        V(mutex);//离开临界区
        V(fullBuffers);//将内容物个数+1
    }
}

void consumer(){
    while(TRUE){
        P(fullBuffers);//内容物个数-1
        P(mutex);
        从缓冲区读取数据;
        V(mutex);
        V(emptyBuffers);//空槽数量+1
    }
}

内存不共享的基于Actor模型的TaskPool并发能力模拟:

import { taskpool } from '@kit.ArkTS';
// 跨线程并发任务
@Concurrent
async function produce(): Promise<number>{
  // 添加生产相关逻辑
  console.log("producing...");
  return Math.random();
}

class Consumer {
  public consume(value : Object) {
    // 添加消费相关逻辑
    console.log("consuming value: " + value);
  }
}

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

  build() {
    Row() {
      Column() {
        Text(this.message)
          .fontSize(50)
          .fontWeight(FontWeight.Bold)
        Button() {
          Text("start")
        }.onClick(() => {
        //此处为并发逻辑
          let produceTask: taskpool.Task = new taskpool.Task(produce);
          let consumer: Consumer = new Consumer();
          for (let index: number = 0; index < 10; index++) {
            // 执行生产异步并发任务
            taskpool.execute(produceTask).then((res : Object) => {
              consumer.consume(res);
            }).catch((e : Error) => {
              console.error(e.message);
            })
          }
        })
        .width('20%')
        .height('20%')
      }
      .width('100%')
    }
    .height('100%')
  }
}

可以看到,TaskPool能力相较于传统共享内存下并发开发的优势在于各线程内存独立,因此不需要对共享资源区的操作加锁,TaskPool线程之间通过序列化信息通讯,生产者线程将信息序列化发送给UI线程,UI线程消费结果后将生产任务发送给生产者,对线程的调度在TaskPool内部实现了封装
在这里插入图片描述

TaskPool支持开发者在主线程封装任务抛给任务队列,系统选择合适的工作线程,进行任务的分发及执行,再将结果返回给主线程。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值