异步并等待产生获取和释放语义吗? [英] Do async and await produce acquire and release semantics?

查看:101
本文介绍了异步并等待产生获取和释放语义吗?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

对于从async方法返回是否总是产生释放语义以及await是否总是产生获取语义,我找不到明确的答案.我认为是的,因为否则,任何async/await代码都将是雷区?

I couldn't find a clear answer about whether returning from an async method always produces release semantics and whether await always produces acquire semantics. I assume yes, because otherwise any async/await code would be a minefield?

所以这是一个例子:是否保证返回的值都为100*212345*2,而没有任何显式的锁或障碍?

So here's an example: are returned values both guaranteed to be 100*2 and 12345*2, without any explicit locks or barriers?

private static async Task<(int, int)> AMethod()
{
    // Runs on the original thread:
    var x = 100;
    var y = 12345;

    var task = Task.Run(() =>
    {
        // Can run on another thread:
        x *= 2;
        y *= 2;

        // Implicit return here, marking the task completed.
        // Release semantics or not?
    });

    await task; // Acquire semantics or not?

    // Runs on the original thread:
    return (x, y);
}

当然,Task.Run还需要产生一个发行版,并且在开始运行任务的代码时需要获取.忘记了原始问题中的内容.

Of course, Task.Run also needs to produce a release and an acquire is needed when starting to run the task's code. Forgot about those in the original question.

推荐答案

是的,保证返回的值都是100*212345*2,没有任何显式的锁或障碍.

Yes, the returned values are both guaranteed to be 100*2 and 12345*2, without any explicit locks or barriers.

在这种情况下,产生内存障碍的是Task.Run,而不是await.

It's the Task.Run, not the await, which produces the memory barrier in this case.

引用 C#中出色的Albahari线程:

以下内容隐式生成完整的篱笆:

The following implicitly generate full fences:

  • C#的lock语句(Monitor.Enter/Monitor.Exit)
  • Interlocked类上的所有方法(我们将在稍后介绍)
  • 使用线程池的异步回调-其中包括异步委托,APM回调和任务延续
  • 设置并等待信令构造
  • 任何与信号有关的东西,例如启动或等待任务
  • C#'s lock statement (Monitor.Enter/Monitor.Exit)
  • All methods on the Interlocked class (we’ll cover these soon)
  • Asynchronous callbacks that use the thread pool — these include asynchronous delegates, APM callbacks, and Task continuations
  • Setting and waiting on a signaling construct
  • Anything that relies on signaling, such as starting or waiting on a Task

借助最后一点,以下内容是线程安全的:

By virtue of that last point, the following is thread-safe:

int x = 0;
Task t = Task.Factory.StartNew (() => x++);
t.Wait();
Console.WriteLine (x);    // 1

Task.Run包装ThreadPool.UnsafeQueueUserWorkItem,它属于使用线程池的异步回调".

Task.Run wraps ThreadPool.UnsafeQueueUserWorkItem, which falls under "Asynchronous callbacks that use the thread pool".

请参阅内存屏障生成器,以获取更全面的创建内存屏障的信息.

See Memory barrier generators for a more comprensive list of things that create memory barriers.

这篇关于异步并等待产生获取和释放语义吗?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆