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:
Ada karyawan yang memiliki pengidentifikasi yang disediakan.
Karyawan yang memiliki gaji yang disediakan ada.
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, ¬_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
Lihat juga
Pustaka Agen Asinkron
Blok Pesan Asinkron
Fungsi Passing Pesan
kelas pilihan
bergabung dengan Kelas