C#Job System中的安全系统
竞争条件 (Race Condition,也叫做资源竞争,是多线程编程中比较头疼的问题)
在编写多线程代码时,总是存在竞争条件的风险。当一个操作的输出取决于其控制之外的另一个过程的时间时,就会发生竞争状态。竞争条件并不总是错误,而是不确定行为的来源。当争用条件确实导致错误时,可能很难找到问题的根源,因为它取决于时间,因此您只能在极少数情况下重现问题。对其进行调试可能会导致问题消失,因为断点和日志记录可能会更改单个线程的时间。竞争条件在编写多线程代码方面带来了最大的挑战。(我想凡是有过多线程开发经历的同学看完这一段后会默默的点个赞,表示认同)
安全系统
为了使编写多线程代码更容易,Unity C#Job System会检测所有潜在的竞争状况,并保护您免受可能引起的错误的影响。
例如:如果C#Job System将对您主线程中的代码中的数据的引用发送到Job,则它无法验证主线程是否在作业写入它的同时正在读取数据。这种情况下创建竞争条件。
C#Job System通过向每个Job发送需要对其进行操作的数据的副本(而不是对主线程中的数据的引用)来解决此问题。此副本隔离了数据,从而消除了竞争状况。(了解ECS的同学应该知道,ECS中的C数据(Component)都定义成了struct而不是class,因为class是引用类型,struct是值类型,值类型才有副本一说)
C#Job System复制数据的方式意味着作业只能访问Blittable数据类型。在托管代码和本地代码(原文是native code 估计翻译成非托管代码)之间传递时,这些类型不需要转换。
C#Job System可以使用memcpy复制Blittable数据类型,并在Unity的托管部分和本地部分之间传输数据。它用于memcpy在安排作业(Scheduling jobs)时将数据放入本机内存,并在执行作业时向被管理方提供对该副本的访问权限。有关更多信息,请参见安排作业(Scheduling jobs)。
Blittable数据类型和非Blittable类型(附加内容)
根据微软的文档以下是Blittable
System.Byte
System.SByte
System.Int16
System.UInt16
System.Int32
System.UInt32
System.Int64
System.IntPtr
System.UIntPtr
如果一个数组的元素是以上类型,比如整形数组
仅包含Blittable类型的值类型
以下是非Blittable类型
System.Array
System.Boolean
System.Char
System.Class
System.Object
System.Mdarray
System.String
System.Valuetype
System.Szarray
关于这部分,可查阅微软官方文档
https://docs.microsoft.com/en-us/previous-versions/dotnet/netframework-1.1/75dwhxf7(v=vs.71)