Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/design-patterns/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 共同例程回调是否线程安全? 背景:_C#_Unity3d_Coroutine - Fatal编程技术网

C# 共同例程回调是否线程安全? 背景:

C# 共同例程回调是否线程安全? 背景:,c#,unity3d,coroutine,C#,Unity3d,Coroutine,根据这一点,Unity Co例程不是多线程的。因此,如果协程回调正在访问一个全局变量,我将假定不会有线程冲突 例子: 经历过这种情况的人能否确认协同路由确实是同步的,或者GlobalVar是线程安全的?最近我在评论中与某人就这一点进行了争论 我现在找不到这些评论,但是 不,协程是并且不能遇到竞争条件。根据定义,所有同步的线程都是线程安全的,您不能仅与1个线程发生线程冲突。请检查上的-游戏逻辑-部分。协程和收益率有一个特定的时间,它们在游戏循环中被调用[游戏循环总是一个线程。我知道没有例外]我不知

根据这一点,Unity Co例程不是多线程的。因此,如果协程回调正在访问一个全局变量,我将假定不会有线程冲突

例子:
经历过这种情况的人能否确认协同路由确实是同步的,或者GlobalVar是线程安全的?

最近我在评论中与某人就这一点进行了争论

我现在找不到这些评论,但是


不,协程是并且不能遇到竞争条件。根据定义,所有同步的线程都是线程安全的,您不能仅与1个线程发生线程冲突。请检查上的-游戏逻辑-部分。协程和收益率有一个特定的时间,它们在游戏循环中被调用[游戏循环总是一个线程。我知道没有例外]我不知道比赛条件是不可能的。当然,如果有一个交叉调用来yield,共享数据的状态可能会改变。更准确的说法是,Unity中的co例程是协作多任务处理,因此没有抢占权。多任务处理中的大多数问题仍然适用——当然是重入、死锁和TOCTOU条件。@Mitch我用我能想到的所有方法测试了它。数据从未按意外顺序进行过修改。不过,我很乐意尝试一些替代方案。考虑两个访问共享状态的调用,更改它,然后将其恢复到前一个状态。嫁妆;var prevBackgroundColor=this.BackgroundColor;this.BackgroundColor=Colors.Red;嫁妆;产量this.BackgroundColor=prevBackgroundColor;。由于在prevBackgroundColor中捕获的共享状态,BackgroundColor可能会变成红色。@Mitch剩余时间较短的协同程序将首先执行其任务。如果两者都有相同的剩余时间,那么首先调用的那个将首先运行。这里不存在争用,因为调用来自单个线程,因此必须首先以确定的方式调用其中一个线程。争用是指整个代码块在再次运行之前是否运行。这可能是因为doWork调用了一个或两个调用被调度程序交错。仍然需要同步,以避免共享背景颜色变为红色。async/await即使是单线程的,也会出现同样的缺陷。
//Declaration
private IEnumerator Resolve(WWW request, Action<WWW> callback)
{
    while (!request.isDone)
    {
        yield return null;
    }

    callback(request);
}

//Invocation - called constantly
StartCoroutine(Resolve(request, request => {GlobalVar = request.text;}));