ジョブの Schedule メソッドを呼び出すと、JobHandle を返します。コード内で JobHandle を他のジョブの依存関係として使用することができます。ジョブが別のジョブの結果に依存している場合は、以下のように、最初のジョブの JobHandle をパラメーターとして Schedule メソッドに渡すことができます。
JobHandle firstJobHandle = firstJob.Schedule();
secondJob.Schedule(firstJobHandle);
ジョブに多くの依存関係がある場合は、JobHandle.CombineDependencies メソッドを使用してそれらを合同できます。CombineDependencies を使うと、依存関係を Schedule メソッドに渡すことが可能です。
NativeArray<JobHandle> handles = new NativeArray<JobHandle>(numJobs, Allocator.TempJob);
// `handles` に複数のスケジュールされたジョブの `JobHandles` を割り当てます...
JobHandle jh = JobHandle.CombineDependencies(handles);
JobHandle を使用すると、ジョブの実行が終了するまでメインスレッドのコードを実行するのを強制的に待機させることができます。これを行うには、JobHandle のメソッド Complete を呼び出します。この時点で、メインスレッドは、ジョブが使っていた NativeContainer に安全にアクセスできます。
注意 ジョブをスケジュールすると、そのままでは実行を開始しません。スケジュールされたジョブがメインスレッドで待機しているときに、ジョブが使用している NativeContainer データにメインスレッドからアクセスする必要がある場合は、JobHandle.Complete メソッドを呼び出します。このメソッドはメモリキャッシュからジョブをフラッシュし、実行のプロセスを開始します。JobHandle の Complete を呼び出すと、そのジョブの NativeContainer タイプの所有権をメインスレッドに返還します。これらの NativeContainer タイプにメインスレッドから安全にアクセスするには、JobHandle の Complete を呼び出す必要があります。ジョブの依存関係の JobHandle で Complete を呼び出すことで、所有権をメインスレッドに返還することも可能です。例えば、 jobA で Complete を呼び出すこともできますし、jobA に依存する jobB で Complete を呼び出すこともできます。どちらの場合でも Complete の呼び出し後に、jobA が使用していた NativeContainer タイプに、メインスレッドから安全にアクセス可能になります。
あるいは、データへのアクセスが必要ない場合は、バッチを明示的にフラッシュする必要があります。これを行うには、静的メソッド JobHandle.ScheduleBatchedJobs を呼び出します。このメソッドを呼び出すとパフォーマンスに悪影響を与える可能性があることに注意してください。
ジョブコードサンプル
// 2 つの浮動小数点の値を加算するジョブ
public struct MyJob : IJob
{
public float a;
public float b;
public NativeArray<float> result;
public void Execute()
{
result[0] = a + b;
}
}
// 1 を値に加算するジョブ
public struct AddOneJob : IJob
{
public NativeArray<float> result;
public void Execute()
{
result[0] = result[0] + 1;
}
}
メインスレッドコードサンプル
//結果を保存するために、1 つの float 値を格納できるネイティブの配列を作成します。この例では、説明のためにジョブが完了するのを待ちます。
NativeArray<float> result = new NativeArray<float>(1, Allocator.TempJob);
//ジョブ1 のデータを設定します
MyJob jobData = new MyJob();
jobData.a = 10;
jobData.b = 10;
jobData.result = result;
//ジョブ1 をスケジュールします
JobHandle handle = jobData.Schedule();
// ジョブ2 のデータを設定します
AddOneJob incJobData = new AddOneJob();
incJobData.result = result;
// ジョブ2 をスケジュールします
JobHandle secondHandle = incJobData.Schedule(firstHandle);
//ジョブ2 が完了するのを待ちます
secondHandle.Complete();
//NativeArray のすべてのコピーが同じメモリを指している場合は、自分の NativeArray のコピーの結果にアクセスできます
float aPlusB = result [0];
//結果の配列に割り当てられたメモリを解放します
result.Dispose();