c# - 如何为 Unity3D 编写线程安全的 C# 代码?

标签 c# multithreading unity3d

我想了解如何编写线程安全代码。

例如我的游戏中有这段代码:

bool _done = false;
Thread _thread;

// main game update loop
Update()
{
    // if computation done handle it then start again
    if(_done)
    {
        // .. handle it ...
        _done = false;
        _thread = new Thread(Work);
        _thread.Start();
    }
}

void Work()
{
     // ... massive computation

     _done = true;
}

如果我理解正确,主游戏线程和我的 _thread 可能有自己的 _done 缓存版本,并且一个线程可能永远看不到 _done 在另一个线程中更改了吗?

如果可以,如何解决?

  1. 是否可以通过仅应用 volatile 关键字来解决。

  2. 或者是否可以通过 Interlocked 的方法如 ExchangeRead 来读取和写入值?

  3. 如果我用 lock (_someObject) 包围 _done 读写操作,我需要使用 Interlocked 或其他东西来防止缓存?

编辑 1

  1. 如果我将 _done 定义为 volatile 并从多个线程调用 Update 方法。在我将 _done 分配给 false 之前,是否有可能有 2 个线程将进入 if 语句?

最佳答案

  1. 是的,但从技术上讲,这不是 volatile 关键字的作用;不过,它有一个副作用——volatile 的大多数用途都是为了那个副作用;实际上 volatile 的 MSDN 文档现在只列出了这种副作用情况 (link) - 我猜想 actual original 措辞(关于重新排序指令)太困惑了?所以也许这现在是官方用法?

  2. Interlocked 没有bool 方法;您需要使用 int0/1 之类的值,但这几乎就是 bool 无论如何 - 请注意Thread.VolatileRead 也可以工作

  3. lock 有一个完整的栅栏;你在那里不需要任何额外的构造,lock 本身就足以让 JIT 理解你需要什么

就个人而言,我会使用volatile。您已经方便地以递增的间接费用顺序列出了您的 1/2/3。 volatile 将是这里最便宜的选择。

关于c# - 如何为 Unity3D 编写线程安全的 C# 代码?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/43274759/

相关文章:

c# - 查找网站信息

java - 使用 SynchronousQueue 解决消费者生产者并发问题。公平属性不起作用

java - 需要有关具有到期时间限制的 hashMap 的帮助

multithreading - 处理长时间运行的 Hibernate 事务中的死锁

unity3d - 切换音频对象仅存在于一个场景中,但可以在所有场景中播放,并在另一场景中打开/关闭

c# - 基于带有滑动手势的对象方向的光线转换

c# - 将 c++ dll 自动包装到 c# 中

C# - 如何检查进程是否成功启动

c# - 在 Unity C# 中禁用附加到游戏对象的脚本

java - C# 字符串/字符串 : Compare string like in Java (by Reference)