unity JobSystem(作业系统)

JobSystem :

unity提供的一套多线程解决方案,使用这个东西可以极大的提升游戏的运行效率

NativeContainer

NativeContainer 是一种托管值类型,为本机内存提供了一个相对安全的 C# 封装器。它包含一个指向非托管分配的指针。与 Unity C# 作业系统一起使用时,NativeContainer 允许作业访问与主线程共享的数据,而不是使用副本。

如何创建一个job

首先创建一个结构体 实现IJob接口,在接口内部实现Excute()方法,作业的任务处理就放在这个函数之中
NativeArray result 是一个返回结果的数组,这是一种共享的数组

[BurstCompile]
public struct MyJob : IJob
{
    public float a;
    public float b;
    public NativeArray<float> result;

    public void Execute()
    {
        result[0] = a + b;
    }
}

如何调度Job

在主线程的update里面可以写入一下代码

		NativeArray<float> result = new NativeArray<float>(1, Allocator.TempJob);
        // 设置作业数据
        MyJob jobData = new MyJob();
        jobData.a = 2f;
        jobData.b = 3f;
        jobData.result = result;
        //调度作业
        JobHandle handle = jobData.Schedule();        
        //等待作业的完成
        jobData.Complete();

        float res = result[0];
        Debug.Log(res);
        //释放托管资源
        result.Dispose();

然后运行即可

JobHandle和依赖项

一个线程的执行需要在另一个线程的结束之后

调用作业的 Schedule 方法时,将返回 JobHandle。可以在代码中使用 JobHandle 作为其他作业的依赖项。如果一个作业依赖于另一个作业的结果,则可以将第一个作业的 JobHandle 作为参数传递给第二个作业的 Schedule 方法,如下所示:

JobHandle firstJobHandle = firstJob.Schedule();
secondJob.Schedule(firstJobHandle);

以下实例实现两个作业的调度

// 将两个浮点值相加的作业
[BurstCompile]
public struct MyJob : IJob
{
    public float a;
    public float b;
    public NativeArray<float> result;

    public void Execute()
    {
        result[0] = a + b;
    }
}

// 将一个值加一的作业
[BurstCompile]
public struct AddOneJob : IJob
{
    public NativeArray<float> result;
    
    public void Execute()
    {
        result[0] = result[0] + 1;
    }
}

主线程

	private void Update()
    {
        NativeArray<float> result = new NativeArray<float>(1, Allocator.TempJob);
        // 设置作业数据
        MyJob jobData = new MyJob();
        jobData.a = 2f;
        jobData.b = 3f;
        jobData.result = result;
        AddOneJob incJobData = new AddOneJob();
        incJobData.result = result;
        //调度作业
        JobHandle handle = jobData.Schedule();
        JobHandle secondHandle = incJobData.Schedule(handle);
        
        //等待作业的完成
        secondHandle.Complete();

        float res = result[0];
        Debug.Log(res);
        result.Dispose();
        
    }

IJobParallelFor

在调度作业时,只能有一个作业正在执行一项任务。在游戏中,通常希望对大量对象执行相同的操作。这个接口可以实现一个作业执行多个任务

// 将两个浮点值相加的作业
public struct MyParallelJob : IJobParallelFor
{
    [ReadOnly]
    public NativeArray<float> a;
    [ReadOnly]
    public NativeArray<float> b;
    public NativeArray<float> result;

    public void Execute(int i)
    {
        result[i] = a[i] + b[i];
    }
}
NativeArray<float> a = new NativeArray<float>(2, Allocator.TempJob);

NativeArray<float> b = new NativeArray<float>(2, Allocator.TempJob);

NativeArray<float> result = new NativeArray<float>(2, Allocator.TempJob);

a[0] = 1.1;
b[0] = 2.2;
a[1] = 3.3;
b[1] = 4.4;

MyParallelJob jobData = new MyParallelJob();
jobData.a = a;  
jobData.b = b;
jobData.result = result;

// 调度作业,为结果数组中的每个索引执行一个 Execute 方法,且每个处理批次只处理一项
JobHandle handle = jobData.Schedule(result.Length, 1);

// 等待作业完成
handle.Complete();

// 释放数组分配的内存
a.Dispose();
b.Dispose();
result.Dispose();
  • 1
    点赞
  • 10
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值