Gewusst wie: Auswählen von abgeschlossenen Aufgaben
In diesem Beispiel wird veranschaulicht, wie mithilfe der concurrency::choice und concurrency::join Klassen, die erste Aufgabe einen Suchalgorithmus auswählen.
Beispiel
Im folgenden Beispiel werden zwei Suchalgorithmen parallel ausgeführt und der erste abzuschließende Algorithmus ausgewählt.In diesem Beispiel wird der employee-Typ definiert, der einen numerischen Bezeichner und ein Gehalt für einen Mitarbeiter enthält.Die find_employee-Funktion sucht den ersten Mitarbeiter, der über den bereitgestellten Bezeichner oder das bereitgestellte Gehalt verfügt.Die find_employee-Funktion verarbeitet auch den Fall, in dem kein Mitarbeiter über den bereitgestellten Bezeichner oder das Gehalt verfügt.Die wmain-Funktion erstellt ein Array von employee-Objekten und sucht nach mehreren Bezeichnern und Gehaltswerten.
Im Beispiel wird mithilfe eines choice-Objekts aus folgenden Fällen eine Auswahl getroffen:
Es ist ein Mitarbeiter vorhanden, der über den bereitgestellten Bezeichner verfügt.
Es ist ein Mitarbeiter vorhanden, der über das bereitgestellte Gehalt verfügt.
Es ist kein Mitarbeiter vorhanden, der über den bereitgestellten Bezeichner oder das Gehalt verfügt.
Für die ersten beiden Fälle im Beispiel wird ein concurrency::single_assignment -Objekt für den Bezeichner und eine andere single_assignment -Objekt für das Gehalt.Für den dritten Fall wird im Beispiel ein join-Objekt verwendet.Das join-Objekt besteht aus zwei zusätzlichen single_assignment-Objekten. Eines dieser Objekte ist für den Fall, in dem kein Mitarbeiter vorhanden ist, der über den bereitgestellten Bezeichner verfügt, und das andere für den Fall, in dem kein Mitarbeiter vorhanden ist, der über das bereitgestellte Gehalt verfügt.Das join-Objekt sendet eine Meldung, wenn jedes seiner Member eine Meldung empfängt.In diesem Beispiel sendet das join-Objekt eine Meldung, wenn kein Mitarbeiter vorhanden ist, der über den bereitgestellten Bezeichner oder das Gehalt verfügt.
Im Beispiel wird ein concurrency::structured_task_group Objekt beide Suchalgorithmen parallel ausführen.Bei jeder Suchaufgabe wird auf eines der single_assignment-Objekte geschrieben, um anzugeben, ob der bestimmte Mitarbeiter vorhanden ist.Im Beispiel wird die concurrency::receive Funktion, um den Index des ersten Puffers zu erhalten, die eine Nachricht enthält und eine switch Block, um das Ergebnis zu drucken.
// 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);
}
Folgende Ergebnisse werden zurückgegeben:
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.
In diesem Beispiel wird die concurrency::make_choice Hilfsfunktion erstellen choice Objekte und die concurrency::make_join Hilfsfunktion erstellen join Objekte.
Kompilieren des Codes
Kopieren Sie den Beispielcode und fügen Sie ihn in ein Visual Studio Projekt, oder fügen Sie ihn in eine Datei mit dem Namen Suchen employee.cpp und führen Sie den folgenden Befehl in ein Visual Studio-Eingabeaufforderungsfenster.
cl.exe /EHsc find-employee.cpp