返回「计算机、信息技术与工程」
Unity Jobsystem问题
本文目录 3 个章节
Unity Jobsystem问题
note · 我的 UWA 问答 本文收录我在 UWA 问答发表的公开回答。问题内容归原提问者;回答保留当时语境,技术结论可能受 Unity 版本、平台和项目条件限制。
问题
using CSharp;
using Unity.Burst;
using Unity.Collections.LowLevel.Unsafe;
using UnityEngine;
using UnityEngine.Jobs;
using Unity.Collections;
using Unity.Jobs;
public class JobTest : MonoBehaviour
{
// Start is called before the first frame update
public Transform t1;
public Transform t2;
public TransformAccessArray TransformAccessArray;
void Start()
{
TransformAccessArray = new TransformAccessArray(50000,64);
}
private JobHandle handle;
// Update is called once per frame
void Update()
{
if (!handle.IsCompleted)
{
return;
}
if (TransformAccessArray.length == 0)
{
TransformAccessArray.Add(t1);
TransformAccessArray.Add(t2);
}
float t = Time.time;
Debug.Log("time:" + t);
NativeList<int> end_list = new NativeList<int>(TransformAccessArray.length,Allocator.TempJob);
NativeList<int> end_id_list = new NativeList<int>(TransformAccessArray.length,Allocator.TempJob);
UpdateJob job = new UpdateJob
{
time = t,
end_list = end_list,
end_id_list = end_id_list,
};
handle = job.Schedule(TransformAccessArray);
handle.Complete();
if (end_id_list.Length != end_list.Length)
{
Debug.LogError("error time:" + t);
}
else
{
Debug.LogWarning("right time:" + t);
}
end_list.Dispose();
end_id_list.Dispose();
}
}
using System;
using Unity.Burst;
using Unity.Collections;
using Unity.Collections.LowLevel.Unsafe;
using UnityEngine;
using UnityEngine.Jobs;
namespace CSharp
{
[BurstCompile]
public struct UpdateJob : IJobParallelForTransform
{
[NativeDisableContainerSafetyRestriction] public NativeList<int> end_list;
[NativeDisableContainerSafetyRestriction] public NativeList<int> end_id_list;
[ReadOnly] public float time;
public void Execute(int index, TransformAccess transform)
{
end_list.Add(index);
end_id_list.Add(index);
int a = end_list.Length;
int b = end_id_list.Length;
}
}
}
执行多线程之后发现,endidlist.Length和 end_list.Length的长度有时候不一样,谁能解答一下
- 提问者:hardy
- 提问时间:2021-03-09 22:55:15
我的回答
这样写的话,两个线程是并行的,并且是线程不安全的:

两个线程对指令的执行的先后顺序是不确定的。
如果两个线程依次对endlist进行Add的话,endlist就会加入两个元素。
如果两个线程同时取得end_list,同时进行Add,就会产生错误——两个线程都执行完后,某个List只添加了一个元素。
可以用如下方法进行验证:
![]()

如果对数据的访问进行加锁,保证一个线程访问list时,另外一个线程无法访问,就不会出现题主所述的问题。不过这多线程执行就没有意义了,相当于顺序执行。
- 回答时间:2021-03-10 02:06:15
- 最后更新:2021-03-10 02:07:28
- 采纳状态:未采纳
来源与关系
- 上位集合:我的 UWA 问答
- UWA 标签:C#编程
- 原始问题:Unity Jobsystem问题
- 源页最后更新:2021-03-10 02:06:15