Cara: Pilih Di Antara Tugas yang Selesai

Contoh ini menunjukkan cara menggunakan konkurensi::pilihan dan konkurensi::join classes untuk memilih tugas pertama untuk menyelesaikan algoritma pencarian.

Contoh

Contoh berikut melakukan dua algoritma pencarian secara paralel dan memilih algoritma pertama yang akan diselesaikan. Contoh ini mendefinisikan employee jenis, yang memegang pengidentifikasi numerik dan gaji untuk karyawan. Fungsi ini find_employee menemukan karyawan pertama yang memiliki pengidentifikasi yang disediakan atau gaji yang disediakan. Fungsi ini find_employee juga menangani kasus di mana tidak ada karyawan yang memiliki pengidentifikasi atau gaji yang disediakan. Fungsi ini wmain membuat array employee objek dan mencari beberapa pengidentifikasi dan nilai gaji.

Contoh menggunakan choice objek untuk memilih di antara kasus-kasus berikut:

  1. Ada karyawan yang memiliki pengidentifikasi yang disediakan.

  2. Karyawan yang memiliki gaji yang disediakan ada.

  3. Tidak ada karyawan yang memiliki pengidentifikasi atau gaji yang disediakan.

Untuk dua kasus pertama, contoh menggunakan objek konkurensi::single_assignment untuk menahan pengidentifikasi dan objek lain single_assignment untuk menahan gaji. Contoh menggunakan join objek untuk kasus ketiga. Objek join terdiri dari dua objek tambahan single_assignment , satu untuk kasus di mana tidak ada karyawan yang memiliki pengidentifikasi yang disediakan, dan satu untuk kasus di mana tidak ada karyawan yang memiliki gaji yang disediakan. Objek join mengirim pesan ketika setiap anggotanya menerima pesan. Dalam contoh ini, join objek mengirim pesan ketika tidak ada karyawan yang memiliki pengidentifikasi atau gaji yang disediakan.

Contoh menggunakan objek konkurensi::structured_task_group untuk menjalankan kedua algoritma pencarian secara paralel. Setiap tugas pencarian menulis ke salah single_assignment satu objek untuk menunjukkan apakah karyawan yang diberikan ada. Contoh menggunakan fungsi konkurensi::receive untuk mendapatkan indeks buffer pertama yang berisi pesan dan switch blok untuk mencetak hasilnya.

// find-employee.cpp
// compile with: /EHsc
#include <agents.h>
#include <ppl.h>
#include <array>
#include <iostream>
#include <random>

using namespace concurrency;
using namespace std;

// Contains information about an employee.
struct employee
{
   int id;
   float salary;
};

// Finds the first employee that has the provided id or salary.
template <typename T>
void find_employee(const T& employees, int id, float salary)
{
   // Holds the salary for the employee with the provided id.
   single_assignment<float> find_id_result;

   // Holds the id for the employee with the provided salary.
   single_assignment<int> find_salary_result;


   // Holds a message if no employee with the provided id exists.
   single_assignment<bool> id_not_found;

   // Holds a message if no employee with the provided salary exists.
   single_assignment<bool> salary_not_found;

   // Create a join object for the "not found" buffers.
   // This join object sends a message when both its members holds a message 
   // (in other words, no employee with the provided id or salary exists).
   auto not_found = make_join(&id_not_found, &salary_not_found);


   // Create a choice object to select among the following cases:
   // 1. An employee with the provided id exists.
   // 2. An employee with the provided salary exists.
   // 3. No employee with the provided id or salary exists.
   auto selector = make_choice(&find_id_result, &find_salary_result, &not_found);
   

   // Create a task that searches for the employee with the provided id.
   auto search_id_task = make_task([&]{
      auto result = find_if(begin(employees), end(employees), 
         [&](const employee& e) { return e.id == id; });
      if (result != end(employees))
      {
         // The id was found, send the salary to the result buffer.
         send(find_id_result, result->salary);
      }
      else
      {
         // The id was not found.
         send(id_not_found, true);
      }
   });

   // Create a task that searches for the employee with the provided salary.
   auto search_salary_task = make_task([&]{
      auto result = find_if(begin(employees), end(employees), 
         [&](const employee& e) { return e.salary == salary; });
      if (result != end(employees))
      {
         // The salary was found, send the id to the result buffer.
         send(find_salary_result, result->id);
      }
      else
      {
         // The salary was not found.
         send(salary_not_found, true);
      }
   });

   // Use a structured_task_group object to run both tasks.
   structured_task_group tasks;
   tasks.run(search_id_task);
   tasks.run(search_salary_task);

   wcout.setf(ios::fixed, ios::fixed);
   wcout.precision(2);

   // Receive the first object that holds a message and print a message.
   int index = receive(selector);
   switch (index)
   {
   case 0:
      wcout << L"Employee with id " << id << L" has salary " 
            << receive(find_id_result);
      break;
   case 1:
      wcout << L"Employee with salary " << salary << L" has id " 
            << receive(find_salary_result);
      break;
   case 2:
      wcout << L"No employee has id " << id << L" or salary " << salary;
      break;
   default:
      __assume(0);
   }
   wcout << L'.' << endl;
   
   // Cancel any active tasks and wait for the task group to finish.
   tasks.cancel();
   tasks.wait();
}

int wmain()
{
   // Create an array of employees and assign each one a 
   // random id and salary.

   array<employee, 10000> employees;
   
   mt19937 gen(15);
   const float base_salary = 25000.0f;
   for (int i = 0; i < employees.size(); ++i)
   {
      employees[i].id = gen()%100000;

      float bonus = static_cast<float>(gen()%5000);
      employees[i].salary = base_salary + bonus;
   }

   // Search for several id and salary values.

   find_employee(employees, 14758, 30210.00);
   find_employee(employees, 340, 29150.00);
   find_employee(employees, 61935, 29255.90);
   find_employee(employees, 899, 31223.00);
}

Contoh ini menghasilkan output berikut.

Employee with id 14758 has salary 27780.00.
Employee with salary 29150.00 has id 84345.
Employee with id 61935 has salary 29905.00.
No employee has id 899 or salary 31223.00.

Contoh ini menggunakan fungsi pembantu konkurensi::make_choice untuk membuat choice objek dan fungsi pembantu konkurensi::make_join untuk membuat join objek.

Mengompilasi Kode

Salin kode contoh dan tempelkan dalam proyek Visual Studio, atau tempelkan dalam file yang diberi nama find-employee.cpp lalu jalankan perintah berikut di jendela Prompt Perintah Visual Studio.

cl.exe /EHsc find-employee.cpp

Baca juga

Pustaka Agen Asinkron
Blok Pesan Asinkron
Fungsi Passing Pesan
kelas pilihan
bergabung dengan Kelas