UnityECS学习日记七:Unity Job System 之 IJob 多线程接口

上篇提到NativeContainer托管的数据类型,为Unity线程和job线程进行数据交换,它的内存分配有三种分配类型,当初始化时需要指定一个合适的分配器。有:

1.Allocator.Temp是最快的分配类型。它适用于分配一个生命周期只有一帧或更短时间的操作。你不应当把一个分配器为Temp类型分配的NativeContainer传递给jobs使用。你同时需要在函数返回之前调用Dispose方法(例如MonoBehaviour.Update,或者其他从原生到托管代码的掉用)。

2.Allocator.TempJob是相比于Temp一个较慢的分配类型,但它比Persistent要快。如果你在四帧内没有掉用Dispose,控制台会打印一个由原生代码生成的警告信息。绝大部分小jobs使用这种类型的NativeContainer分配器。

3.Allocator.Persistent是最慢的分配类型,但它可以持续存在到你需要的时间,如果必要的话可以贯穿应用程序的整个生命周期。它是直接调用malloc的一个封装。长时间的job可以使用这种分配类型。当性能比较紧张的时候你不应当使用Persistent。


IJob 作业系统的其中一个接口,其次还要知道:

1.JOB是一个一个的开线程任务,因为数据是顺序执行的所以它可以保证正确性。

2.如果想让线程人物真正的并行,那么可以采用IJobParallelFor。

3.一旦线程任务并行的话,意味着数据的执行顺序不是线性的,每一个Job里的数据不能完全依赖上一个Job执行后的结果。

4.[ReadOnly]声明数据只是制度,如果数据是只读的,意味着这个数据不需要枷锁。

5.如果不声明默认数据是Read/WriteDE的,数据一旦需要改写,那么Job就一定要等它。

6.然而这一切Unity都已经帮我们做好了,我们并不需要自己做枷锁解锁逻辑。


 

案例五:IJob多线程控制指定数量cube向上移动(Scne6)

脚本:IJobTest 

using UnityEngine;
using Unity.Jobs;
using Unity.Collections;

public class IJobTest : MonoBehaviour
{
    struct VelocityJob : IJob
    {
        public NativeArray<Vector3> positions;
        public NativeArray<Vector3> velocitys;
        public float delaTime;
        public void Execute()
        {
            for (int i = 0; i < positions.Length; i++)
            {
                positions[i] = positions[i] + velocitys[i] * delaTime;
            }
        }
    }
    public int gameCount = 300;
    public GameObject prefab;
    public GameObject[] gameObjs;
    void Start()
    {
        gameObjs = new GameObject[gameCount];
        for (int i = 0; i < gameCount; i++)
        {
            gameObjs[i] = Instantiate<GameObject>(prefab);
            gameObjs[i].transform.position = UnityEngine.Random.insideUnitSphere*40;
        }

    }


    void Update()
    {
        // 1.准备数据
        NativeArray<Vector3> tmpPositions = new NativeArray<Vector3>(gameCount, Allocator.TempJob);
        NativeArray<Vector3> tmpVelocitys = new NativeArray<Vector3>(gameCount, Allocator.TempJob);
        for (int i = 0; i < gameCount; i++)
        {
            tmpVelocitys[i] = new Vector3(0, 1, 0);
            //tmpPositions[i] = tmpPositions[i] + tmpVelocitys[i] * Time.deltaTime;
            tmpPositions[i] = gameObjs[i].transform.position;
        }
        VelocityJob job = new VelocityJob()
        {
            positions = tmpPositions,
            delaTime = Time.deltaTime,
            velocitys = tmpVelocitys
        };
        // 2.执行  
        //信号量 主线程如何知道子线程执行完毕
        JobHandle jobHandle = job.Schedule();

        // 3.同步
        jobHandle.Complete();

        for (int i = 0; i < gameCount; i++)
        {
            gameObjs[i].transform.position = tmpPositions[i];
        }


        tmpPositions.Dispose();
        tmpVelocitys.Dispose();
    }
}

 

如上图,通过预制体,动态生成了300个cube,而cube向上移动的数据,是通过多线程进行计算的。

 

 远程项目仓库(github):https://github.com/h1031464180/UnityECS

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值