task

fnauto task(alias fun, Args...)(Args args)

Creates a Task on the GC heap that calls an alias. This may be executed via Task.executeInNewThread or by submitting to a

TaskPool. A globally accessible instance of

TaskPool is provided by taskPool.

Returns

A pointer to the Task.

Example:

// Read two files into memory at the same time.
import std.file;

void main()
{
   // Create and execute a Task for reading
   // foo.txt.
   auto file1Task = task!read("foo.txt");
   file1Task.executeInNewThread();

   // Read bar.txt in parallel.
   auto file2Data = read("bar.txt");

   // Get the results of reading foo.txt.
   auto file1Data = file1Task.yieldForce;
}

// Sorts an array using a parallel quick sort algorithm.
// The first partition is done serially.  Both recursion
// branches are then executed in parallel.
//
// Timings for sorting an array of 1,000,000 doubles on
// an Athlon 64 X2 dual core machine:
//
// This implementation:               176 milliseconds.
// Equivalent serial implementation:  280 milliseconds
void parallelSort(T)(T[] data)
{
   // Sort small subarrays serially.
   if (data.length < 100)
   {
        std.algorithm.sort(data);
        return;
   }

   // Partition the array.
   swap(data[$ / 2], data[$ - 1]);
   auto pivot = data[$ - 1];
   bool lessThanPivot(T elem) { return elem < pivot; }

   auto greaterEqual = partition!lessThanPivot(data[0..$ - 1]);
   swap(data[$ - greaterEqual.length - 1], data[$ - 1]);

   auto less = data[0..$ - greaterEqual.length - 1];
   greaterEqual = data[$ - greaterEqual.length..$];

   // Execute both recursion branches in parallel.
   auto recurseTask = task!parallelSort(greaterEqual);
   taskPool.put(recurseTask);
   parallelSort(less);
   recurseTask.yieldForce;
}

fnauto task(F, Args...)(F delegateOrFp, Args args) if (is(typeof(delegateOrFp(args))) && !isSafeTask!F)

Creates a Task on the GC heap that calls a function pointer, delegate, or class/struct with overloaded opCall.

Example:

// Read two files in at the same time again,
// but this time use a function pointer instead
// of an alias to represent std.file.read.
import std.file;

void main()
{
   // Create and execute a Task for reading
   // foo.txt.
   auto file1Task = task(&read!string, "foo.txt", size_t.max);
   file1Task.executeInNewThread();

   // Read bar.txt in parallel.
   auto file2Data = read("bar.txt");

   // Get the results of reading foo.txt.
   auto file1Data = file1Task.yieldForce;
}

Notes: This function takes a non-scope delegate, meaning it can be used with closures. If you can't allocate a closure due to objects on the stack that have scoped destruction, see scopedTask, which takes a scope delegate.

fn@trusted auto task(F, Args...)(F fun, Args args) if (__traits(compiles, () @safe => fun(args)) && isSafeTask!F)

Version of task usable from @safe code. Usage mechanics are identical to the non-@safe case, but safety introduces some restrictions:

  1. fun must be @safe or @trusted.
  1. F must not have any unshared aliasing as defined by
hasUnsharedAliasing. This means it

may not be an unshared delegate or a non-shared class or struct with overloaded opCall. This also precludes accepting template alias parameters.

  1. Args must not have unshared aliasing.
  1. fun must not return by reference.
  1. The return type must not have unshared aliasing unless fun is

pure or the Task is executed via executeInNewThread instead of using a TaskPool.