Concurrency Roadmap Misc Interoperability with Objective-C
Total Page:16
File Type:pdf, Size:1020Kb
Goal: make concurrent programs simpler to reason about and safer (no data races) Data race = two threads access the same data Data races in memory concurrently (at least one writer) Increasing the priority of a task The mechanism to prevent data can automatically increase the Because the child tasks are races proactively priority of the child tasks known Data isolation Actor-local data, and each actor is single- When a higher-priority task waits on threaded (or serial-queued) internally a lower-priority task, the priority of all child tasks can be escalated An actor performs local computation on its own private state This is the timeout problem Nathaniel Smith wrote about in In the form of calling async Examples of systemic Limiting the total time spent on a his blog posts on structured instance methods task management task (including its child tasks) concurrency "by only allowing asynchronous instance problems this can solve Cancelling a task also cancels Actors send messages methods of actor classes to be invoked from "This eliminates the need for any queuing or its child tasks to other actors outside the actor, we ensure that all synchronization within the synchronous Semantics synchronous methods are already inside the code, making such code more efficient and Structured concurrency = concurrent "Task-local storage" can be actor when they are called" simpler to write" programs are organized into tasks and picked up by child tasks child tasks rather than simply a sea of Messages can't be sync It's possible this restriction could be lifted under formally-unrelated threads and jobs Child tasks can communicate up certain circumstances, e.g. when the caller is in the task hierarchy, e.g. when an async context and waits the sync call they get flooded and need the A cooperative approach to parent to slow down handling pressure Actors act on messages received from other actors The proposal essentially reads like NSOperation, but with Syntax: `actor class BankAccount { … }` compiler support Like classes, but with compiler- = actor isolation Slava Pestov: "I’m considering dying on the enforced protection from data races Allow the programmer to compose for the actor's state multiple async (and non-async) The compiler translates an async “Well Actually async/await is a control flow There are holes in the Properties of mutable reference operations with the language's function into an appropriate set of structure and not a concurrency primitive” hill" protection, though Examples types (classes, pointers) normal control flow structures closures and state machines. Async functions can be suspended, which Every actor has a private serial Async instance methods are Sequentially, but not necessarily queue/exclusive executor executed on this executor in enqueuing order Document will eventually be at Difficult to read Pyramid of doom implies that another task can run on the same docs/ConcurrencyRoadmap.md thread. This sounds like concurrency to me Becomes nested/duplicated Actor classes can't inherit from Exception: inheriting from I don't fully understand this The proposal uses the word non-actor classes NSObject is allowed Goal: make concurrent programming Error handling Actor classes in Swift convenient, efficient, and safe Not compatible with throws "concurrency" more as a synonym for syntax what Jakob Jenkov calls "parallelism" Actor classes are a restricted form of class Manifesto might describe Problems with typical callback- "async/await does not introduce multiple possible directions Conditional execution is hard concurrency per se: ignoring the Example: makeDinner() function in proposal motivation based async code and error-prone section: Should actors (being a new Is inheritance required to bring Not a manifesto suspension points within an asynchronous Support inheritance concept) even support inheritance? UIKit etc. into the actor world? This describes a single plan function, it will execute in essentially the Forget to call callback in one or Where actor classes act like same manner as a synchronous function" func makeDinner() async throws -> Meal { Satisfy AnyObject constraints make asynchronous programming Easy to make mistakes more code paths let veggies = await try chopVegetables() classes convenient and clear at the point of use Too many APIs are not defined let meat = await marinateMeat() But classes are not the only Motivation: async/await alone Are reference types reference types in Swift provide a standard set of asynchronously because To execute an async function's let oven = await try preheatOven(temperature: 350) does not provide concurrency! Why call them "actor classes", language tools and techniques callbacks are awkward They mean that a single async subtasks in parallel, we need The first three subtasks should It's about control flow! function still executes another mechanism to build on let dish = Dish(ingredients: [veggies, meat]) not merely "actors"? Chris Lattner: "I think it is reasonable for run in parallel actors to not have static members and class Intended end state improve the performance of asynchronous Allow async code to be written What's the point of "ignoring the sequentially, even if it can be top of async/await = structured return await try oven.cook(dish, duration: .hours(3)) methods though, as the whole idea is to get rid code through better knowledge at compile time as straight-line code suspension points" suspended in between. concurrency } The subtasks also have dependencies: `cook` can't begin of global state" eliminate data races and deadlocks in the (1) better performance for until the first three are done "The similarities end at being "a same way Swift eliminates memory unsafety asynchronous code reference rather than a value", Advantages of async functions Allow the compiler to directly Even if there's only one CPU, Introduction will span multiple Swift releases (2) better tooling to provide a ktoso: conflating actors and however the semantic E.g. an actor could also be reason about the execution pattern "Concurrency means that an switching between multiple tasks more consistent experience classes may be capabilities the two expose are distributed (living on another of the code, allowing callbacks to application is making progress Will allow uses to organize their while debugging, profiling, and "concurrency is related to how counterproductive very different" machine) run far more efficiently on more than one task at the code around actors; will reduce, exploring code an application handles multiple but not eliminate, data races same time (concurrently)" tasks it works on: one task at at Other code that has a reference (3) a foundation for future time (sequentially) or multiple to the actor can't modify state async/await concurrency features like task tasks at the same time Mutable stored properties Task API and Structured Concurrency priority and cancellation (concurrently)" Actor-isolated Computed properties Ability to protect global variables with "In practice, asynchronous "Parallelism is related to how an members by default Phase 1: async syntax and actor global actors functions are compiled to not Jakob Jenkov: concurrency vs. application handles each Subscripts types the function and all of its depend on the thread during an parallelism "Parallelism means that an application splits individual task: process the task Protect class members by converting asynchronous callers asynchronous call, so that only Synchronous instance methods Safety benefits covered in its tasks up into smaller subtasks which can serially from start to end, or split the class to an actor class It only gives up its thread at a simultaneously abandon the the innermost function needs to phase one be processed in parallel, for instance on the task up into subtasks which = External access is allowed Async function = "think of an asynchronous suspension point (marked by await) thread. do any extra work." multiple CPUs at the exact same time" can be completed in parallel" Frameworks that require access on a function as an ordinary function that has the Types with value semantics that particular queue can define a global actor A synchronous function can't call an special power to give up its thread" By this definition, it's a question of where This is only safe for value types are mutably captured by a Actors and (partial) Actor Isolation and default protocols to it async function because the former you draw the line between "multiple Proposals (better: types with value semantics) closure are also problematic doesn't know how to give up its thread. tasks" and "one task split into subtasks" Global variables will not be A `let` to a (potentially nested, Race conditions not covered in threadsafe by default "This is an interesting question that I'm not sure we Like a thread, a task runs one hidden) mutable reference type is See "Escaping reference types" phase one have a clear answer to. There's an ambiguity between async function at a time Actor-independent Non-actor reference types a function that's "generic" about its executor (e.g. by default Constants (`let`) unsafe in the proposal When a function makes an async call, Actors only allow access to their Concurrency interop with Obj-C because it takes an argument that can only be safely "a task is to asynchronous This is a problem for library evolution the called function is still running as part members directly on `self` called or otherwise used on that executor) and a Every async functions runs in a functions, what a thread is to because turning a `let` into a computed You can use of the same task (and the caller waits Using the @asyncHandler function that's apathetic about its executor (e.g. task synchronous functions" `var` is no longer a resilient change `@actorIndependent var` attribute because it's in an I/O library and is just kicking off work for it to return) and waiting for a response)" Declarations marked with ability to declare a synchronous "So e.g.