Unity C# Job System介绍(三) Job的创建和调度
創建Jobs
Unity - Manual: Creating jobs?docs.unity3d.com
為了在Unity中創建一個job你需要實現IJOb接口。IJob允許你調度一個job,和其他jobs并發執行。Unity - Manual: Creating jobs為了在Unity中創建一個job你需要實現IJOb接口。IJob允許你調度一個job,和其他jobs并發執行。
注意:“job”是Unity中所有實現了IJob接口的結構的總稱。
為了創建一個job,你需要:?創建一個實現IJob的結構體?添加job需要使用的成員變量(可以是blittable類型或NativeContainer類型) * 在結構體中添加一個叫Execute的方法并將job的具體邏輯實現放在里面
當job執行的時候,Excute方法在單個核心上運行一次
注意:當設計你的job時,記住你是在一份數據的拷貝上進行操作的,除了在使用NativeContainer的情況下。所以,在主線程訪問一個job中數據的唯一方法就是將數據寫入NativeContainer。
一個簡單job定義的例子
// Job adding two floating point values together public struct MyJob : IJob {public float a;public float b;public NativeArray<float> result;public void Execute(){result[0] = a + b;} }調度Jobs
Unity - Manual: Scheduling jobs?docs.unity3d.com
為了在主線程中調度一個job,你必須:?實例化一個job?填充job中的數據 * 調用Schedule方法
在合適的時間調用Schedule將job放入到job的執行隊列中。一旦job被調度,你不能中途打斷一個job的執行。
注意:你只能從主線程中調用Schedule
調度一個job的例子
// Create a native array of a single float to store the result. This example waits for the job to complete for illustration purposes NativeArray<float> result = new NativeArray<float>(1, Allocator.TempJob);// Set up the job data MyJob jobData = new MyJob(); jobData.a = 10; jobData.b = 10; jobData.result = result;// Schedule the job JobHandle handle = jobData.Schedule();// Wait for the job to complete handle.Complete();// All copies of the NativeArray point to the same memory, you can access the result in "your" copy of the NativeArray float aPlusB = result[0];// Free the memory allocated by the result array result.Dispose();JobHandle和依賴關系
當你調用Schedule方法時會返回一個JobHandle。你可以在代碼中使用JobHandle作為其他jobs的依賴關系。如果一個job依賴于另一個job的結果,你可以將第一個job的JobHandle作為參數傳遞給第二個job的Schedule方法,像這樣:
JobHandle firstJobHandle = firstJob.Schedule(); secondJob.Schedule(firstJobHandle);組合依賴關系
如果一個job有多個依賴項,你可以使用JobHandle.CombineDependencies方法來合并他們。CombineDependencies允許你將他們傳遞給Schedule方法。
NativeArray<JobHandle> handles = new NativeArray<JobHandle>(numJobs, Allocator.TempJob);// Populate `handles` with `JobHandles` from multiple scheduled jobs...JobHandle jh = JobHandle.CombineDependencies(handles);在主線程中等待jobs結束
使用JobHandle來讓你的代碼在主線程等待直到你的job執行完畢。為了做到這樣,需要在JobHandle上調用Complete方法。這樣的話,你就確定主線程可以安全訪問job之前使用的NativeContainer。
注意:jobs不是在你調度他們的時候就立刻開始執行。如果你在主線程中等待job,并且你需要訪問job正在使用的NativeContainer,你可以調用JobHandle.Complete方法。這個方法會刷新內存緩存中的jobs并開始執行。調用JobHandele的Complete會將job的NativeContainer類型數據的歸屬權交還給主線程。你需要在JobHandle上調用Complete來在主線程再次安全地訪問這些NativeContainer類型。你也可以調用一個由job依賴產生的JobHandle的Complete方法來將數據的歸屬權交還給主線程。舉例來說,你可以調用jobA的Complete方法,或者你可以調用依賴于jobA的jobB的Complete方法。兩種方法都可以讓你在調用Complete后在主線程安全訪問jobA使用的NativeContainer類型。
否則,如果你不需要對數據的訪問,但你需要明確地刷新這個批次的job。為了做到這點,調用靜態方法JobHandle.ScheduleBatchedJobs。注意這個調用會對性能產生負面的影響。
一個關于多重job和依賴的例子
job的代碼:
// Job adding two floating point values together public struct MyJob : IJob {public float a;public float b;public NativeArray<float> result;public void Execute(){result[0] = a + b;} }// Job adding one to a value public struct AddOneJob : IJob {public NativeArray<float> result;public void Execute(){result[0] = result[0] + 1;} }主線程代碼:
// Create a native array of a single float to store the result in. This example waits for the job to complete NativeArray<float> result = new NativeArray<float>(1, Allocator.TempJob);// Setup the data for job #1 MyJob jobData = new MyJob(); jobData.a = 10; jobData.b = 10; jobData.result = result;// Schedule job #1 JobHandle firstHandle = jobData.Schedule();// Setup the data for job #2 AddOneJob incJobData = new AddOneJob(); incJobData.result = result;// Schedule job #2 JobHandle secondHandle = incJobData.Schedule(firstHandle);// Wait for job #2 to complete secondHandle.Complete();// All copies of the NativeArray point to the same memory, you can access the result in "your" copy of the NativeArray float aPlusB = result[0];// Free the memory allocated by the result array result.Dispose();?
總結
以上是生活随笔為你收集整理的Unity C# Job System介绍(三) Job的创建和调度的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 双十一浦发银行优惠活动多多!满减福利、礼
- 下一篇: Unity C# Job System介