Do async and await produce acquire and release semantics?

守給你的承諾、 提交于 2020-08-10 05:29:05

问题


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?

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);
}

EDIT: 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.


回答1:


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

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

To quote the wonderful Albahari Threading in C#:

The following implicitly generate full fences:

  • 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 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.



来源:https://stackoverflow.com/questions/55138674/do-async-and-await-produce-acquire-and-release-semantics

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!