Search code examples
c#multithreadingsynchronizationprogramming-languagesfuture

What does it mean by saying that future achieves implicit synchronization?


From Programming Language Pragmatics, by Scott

13.4.5 Implicit Synchronization

In several shared-memory languages, the operations that threads can perform on shared data are restricted in such a way that synchronization can be implicit in the operations themselves, rather than appearing as separate, explicit operations.

We have seen one example of implicit synchronization already: the forall loop of HPF and Fortran 95 (Example 13.10). Separate iterations of a forall loop proceed concurrently, semantically in lock-step with each other: each iteration reads all data used in its instance of the first assignment statement before any iteration updates its instance of the left-hand side. The left-hand side updates in turn occur before any iteration reads the data used in its instance of the second assignment statement, and so on. Compilation of forall loops for vector machines, while far from trivial, is more or less straightforward. On a more conventional multiprocessor, however, good performance usually depends on high-quality dependence analysis, which allows the compiler to identify situations in which statements within a loop do not in fact depend on one another, and can proceed without synchronization.

Futures

Implicit synchronization can also be achieved without compiler analysis. ...

Using C#’s Task Parallel Library (TPL), we might write

var description = Task.Factory.StartNew(() => GetDescription());
var numberInStock = Task.Factory.StartNew(() => GetInventory());
...
Console.WriteLine("We have " + numberInStock.Result
+ " copies of " + description.Result + " in stock");

Static library class Task.Factory is used to generate futures, known as “tasks” in C#. The Create method supports generic type inference, allowing us to pass a delegate compatible with Func<T> (function returning T), for any T. We’ve specified the delegates here as lambda expressions. If GetDescription returns a String, description will be of type Task<String>; if GetInventory returns an int, numberInStock will be of type Task<int>.

The book lists future under the section of implicit synchronization, which also contains both independent iterations in a for-loop and future.

  1. Does "implicit synchronization" mean no need for synchronization?

  2. What does it mean by saying that future (e.g. C#'s task) achieves implicit synchronization?

  3. In C#, do a task and the main program which starts it proceed without the need of synchronization between each other?

    Is a future used only when the computation of the future and the main program which creates the future don't need synchronization between each other?

Thanks.


Solution

  • Synchronization in this context means (quote from wikipedia):

    Process synchronization refers to the idea that multiple processes are to join up or handshake at a certain point, in order to reach an agreement or commit to a certain sequence of action

    Task (as an example of "future" concept) provides a way to start concurrent process and obtain its result in future, by accessing Result property (it does not always start concurrent process, but it does not matter here). So by calling Result you achieve synchronization between your current thread of execution and concurrent thread of execution represented by Task (because your thread potentially waits for task to complete). It's implicit because you just access regular property not using special synchronization constructs. Compare that to signalling with ManualResetEvent - you achieve the same goal but it's explicit this time.