How to: Use Cancellation to Break from a Parallel Loop

This example shows how to use cancellation to implement a parallel search algorithm.

Example

The following example uses cancellation to search for an element in an array. The parallel_find_any function uses the Concurrency::parallel_for algorithm and a Concurrency::structured_task_group object to search for the position that contains the given value. When a work function finds the value, it calls the Concurrency::structured_task_group::cancel method to cancel future work. The runtime cancels any active tasks and does not start new ones.

// parallel-array-search.cpp
// compile with: /EHsc
#include <ppl.h>
#include <iostream>
#include <random>

using namespace Concurrency;
using namespace std;

// Returns the position in the provided array that contains the given value, 
// or -1 if the value is not in the array.
template<typename T>
int parallel_find_any(const T a[], size_t count, const T& what)
{
   // The position of the element in the array. 
   // The default value, -1, indicates that the element is not in the array.
   int position = -1;

   // Use parallel_for to search for the element. 
   // The task group enables a work function to cancel the overall 
   // operation when it finds the result.

   structured_task_group tasks;
   tasks.run_and_wait([&]
   {
      parallel_for(std::size_t(0), count, [&](int n) {
         if (a[n] == what)
         {
            // Set the return value and cancel the remaining tasks. 
            position = n;            
            tasks.cancel();
         }
      });
   });

   return position;
}

int wmain()
{
   const size_t count = 10000;
   int values[count];

   // Fill the array with random values.
   mt19937 gen(34);
   for (size_t i = 0; i < count; ++i)
   {
      values[i] = gen()%10000;
   }

   // Search for any position in the array that contains value 3123.
   const int what = 3123;
   int position = parallel_find_any(values, count, what);
   if (position >= 0)
   {
      wcout << what << L" is at position " << position << L'.' << endl;
   }
   else
   {
      wcout << what << L" is not in the array." << endl;
   }  
}

The following shows sample output for this example.

3123 is at position 4739.

The Concurrency::parallel_for algorithm acts concurrently. Therefore, it does not perform the operations in a pre-determined order. If the array contains multiple instances of the value, the result can be any one of its positions.

Compiling the Code

Copy the example code and paste it in a Visual Studio project, or paste it in a file that is named parallel-array-search.cpp and then run the following command in a Visual Studio 2010 Command Prompt window.

cl.exe /EHsc parallel-array-search.cpp

See Also

Reference

parallel_for Function

structured_task_group Class

Concepts

Cancellation in the PPL

Parallel Algorithms