unity中使用Job
-
效率最高,unity 专门开辟了一个线程池来执行 Job,用这个执行多线程任务效率最高
- 首先直接用线程池中的线程,省掉线程分配和释放
- 其次会根据cpu数量分配合适的线程数量,避免恶性竞争cpu,产生过多的上下文切换
-
应用场景
- 1个任务,只能用异步
用同步会在主线程执行,不会提升效率 - 1个任务同时依赖其它多个任务,可以用异步或同步
不管用同步或异步都会在其它线程执行 - 1个并行任务,可以用异步或同步,如果任务重,照样会卡,此时只能用异步
用同步会给主线程也分配任务,用异步不会给主线程分配任务
- 1个任务,只能用异步
-
普通作业
// 定义作业,就是定义实现 IJob 的结构体 // 必须是结构体,因为要进行克隆操作 public struct MyJob : IJob { // 成员变量,只能是 blittable 类型,就是常用的可直接跟C通信的值类型 // 和 NativeContainer 类型,比如 NativeArray NativeSlice NativeList NativeQueue 等 // NativeContainer 类型其实就是c内存的c#包装类 // 因为在别的线程实际上是复制了一个结构体过去执行时,因此值类型成员其实是拷贝了一份 // 只有 NativeContainer 成员指向的内存是相同的,因此返回值必须放在 NativeContainer 内 [ReadOnly] // 只读,一般用于输入参数 [DeallocateOnJobCompletion] // 任务完成自动调用 Dispose public NativeArray<float> data; public float a; public float b; [WriteOnly] // 只写,一般用于返回值 public NativeArray<float> result; // 实现 Execute 函数 // MyJob 实例将被复制一份在多线程中执行 // 因此 MyJob 必须是结构体 public void Execute() { Debug.Log($"Execute ThreadId={ Thread.CurrentThread.ManagedThreadId}"); result[0] = a + b; } } public class TestJob { // 创建作业 private static MyJob CreateJob() { MyJob jobData = new MyJob(); jobData.a = 10; jobData.b = 10; jobData.result = new NativeArray<float>(1, Allocator.TempJob); // 必须用 Allocator.TempJob 或 Allocator.Persistent return jobData; } private static void ReleaseJob(MyJob job) {