Megosztás a következőn keresztül:


Az egyidejűségi futtatókörnyezet áttekintése

Ez a dokumentum áttekintést nyújt az egyidejűségi futtatókörnyezetről. Ismerteti az egyidejűségi futtatókörnyezet előnyeit, a használatát, valamint azt, hogy összetevői hogyan kommunikálnak egymással, valamint az operációs rendszerrel és az alkalmazásokkal.

Szakaszok

Ez a dokumentum a következő szakaszokat tartalmazza:

Egyidejűségi futtatókörnyezet implementálási előzményei

A Visual Studio 2010 és 2013 közötti verzióiban a Concurrency Runtime az msvcr100.dll és msvcr120.dllközött lett beépítve. Amikor az UCRT újrabontása a Visual Studio 2015-ben történt, a DLL három részre lett újrabontásra:

  • ucrtbase.dll – C API, Windows 10 részeként szállítva, és régebbi verziókhoz Windows Update-en keresztül frissített

  • vcruntime140.dll – A Fordító támogatási funkciói és az EH-futtatókörnyezet a Visual Studión keresztül szállítva

  • concrt140.dll – Concurrency Runtime, a Visual Studión keresztül szállítva. Szükséges párhuzamos tárolókhoz és algoritmusokhoz, például concurrency::parallel_for. Az STL-hez emellett a Windows XP-n található DLL-hez is szükség van a szinkronizálási primitívek energiaellátásához, mivel a Windows XP nem rendelkezik feltételváltozókkal.

A Visual Studio 2015-ben és újabb verzióiban az egyidejűségi futtatókörnyezeti feladatütemező már nem a ppltasks.h feladatosztályának és kapcsolódó típusainak ütemezője. Ezek a típusok mostantól a Windows ThreadPoolt használják a Jobb teljesítmény és a Windows-szinkronizálási primitívekkel való együttműködés érdekében.

Miért fontos az egyidejűség futtatókörnyezete?

Az egyidejűség futtatókörnyezete egységességet és kiszámíthatóságot biztosít az egyidejűleg futó alkalmazások és alkalmazásösszetevők számára. Az egyidejűségi futtatókörnyezet előnyeire két példa: kooperatív feladatütemezés és kooperatív blokkolás.

Az egyidejűségi futtatókörnyezet egy együttműködési feladatütemezőt használ, amely egy munkalopási algoritmust implementál a munka hatékony elosztásához a számítási erőforrások között. Vegyük például azt az alkalmazást, amelynek két szála ugyanazzal a futtatókörnyezettel van felügyelve. Ha az egyik szál befejezi az ütemezett feladatát, ki tudja kapcsolni a munkát a másik szálról. Ez a mechanizmus kiegyensúlyozza az alkalmazás teljes számítási feladatait.

Az egyidejűségi futtatókörnyezet olyan szinkronizálási primitíveket is biztosít, amelyek kooperatív blokkolással szinkronizálják az erőforrásokhoz való hozzáférést. Vegyük például azt a feladatot, amelyhez kizárólagos hozzáféréssel kell rendelkeznie egy megosztott erőforráshoz. A kooperatív blokkolással a futtatókörnyezet a fennmaradó kvantum használatával egy másik feladatot hajthat végre, amikor az első tevékenység az erőforrásra vár. Ez a mechanizmus elősegíti a számítási erőforrások maximális használatát.

[Felső]

Építészet

Az egyidejűségi futtatókörnyezet négy összetevőre oszlik: a párhuzamos minták kódtárára (PPL), az aszinkron ügynökök tárára, a feladatütemezőre és a Resource Managerre. Ezek az összetevők az operációs rendszer és az alkalmazások között találhatók. Az alábbi ábra bemutatja, hogyan működnek együtt az egyidejűségi futtatókörnyezet összetevői az operációs rendszer és az alkalmazások között:

Egyidejűségi futtatókörnyezet architektúrája

Az egyidejűségi futtatókörnyezet architektúrája.

Fontos

A Feladatütemező és a Resource Manager-összetevők nem érhetők el univerzális Windows-platform (UWP) alkalmazásból, illetve ha a feladatosztályt vagy más típusokat használja a ppltasks.h-ban.

Az egyidejűségi futtatókörnyezet rendkívül összeállítható, azaz a meglévő funkciók kombinálásával további műveleteket végezhet. Az egyidejűségi futtatókörnyezet számos funkciót, például párhuzamos algoritmust alkot az alacsonyabb szintű összetevőkből.

Az egyidejűségi futtatókörnyezet olyan szinkronizálási primitíveket is biztosít, amelyek kooperatív blokkolással szinkronizálják az erőforrásokhoz való hozzáférést. További információ ezekről a szinkronizálási primitívekről: Szinkronizálási adatstruktúrák.

A következő szakaszok rövid áttekintést nyújtanak arról, hogy az egyes összetevők mit és mikor érdemes használni.

Párhuzamos minták könyvtára

A párhuzamos minták kódtára (PPL) általános célú tárolókat és algoritmusokat biztosít a részletes párhuzamosság végrehajtásához. A PPL lehetővé teszi az imperatív adat-párhuzamosságot azáltal, hogy párhuzamos algoritmusokat biztosít, amelyek számítási feladatokat osztanak ki gyűjteményeken vagy adathalmazokon a számítási erőforrások között. Emellett lehetővé teszi a tevékenységek párhuzamosságát azáltal, hogy olyan tevékenységobjektumokat biztosít, amelyek több független műveletet osztanak ki a számítási erőforrások között.

A párhuzamos minták kódtára akkor használható, ha olyan helyi számítással rendelkezik, amely kihasználhatja a párhuzamos végrehajtás előnyeit. A concurrency::parallel_for algoritmus használatával például átalakíthat egy meglévő for hurkot, hogy párhuzamosan működjön.

A párhuzamos minták kódtárával kapcsolatos további információkért lásd: Párhuzamos minták könyvtára (PPL).

Aszinkron ügynökök könyvtára

Az aszinkron ügynökök kódtára (vagy csak az Ügynökök tára) egy aktoralapú programozási modellt és üzenetátadási felületet biztosít a durva szemcsés adatfolyamokhoz és a pipelining feladatokhoz. Az aszinkron ügynökök lehetővé teszik a késés hatékony kihasználását azáltal, hogy más összetevők várnak az adatokra.

Használja az Ügynökkódtárat, ha több olyan entitással rendelkezik, amelyek aszinkron módon kommunikálnak egymással. Létrehozhat például egy olyan ügynököt, amely adatokat olvas be egy fájlból vagy hálózati kapcsolatból, majd az üzenetátadó felületek használatával elküldi az adatokat egy másik ügynöknek.

Az Ügynöki könyvtárról további információt az Aszinkron ügynöki könyvtár-ban talál.

Feladatütemező

A Feladatütemező futásidőben ütemezi és koordinálja a tevékenységeket. A Feladatütemező együttműködő, és egy munkalopó algoritmussal éri el a feldolgozási erőforrások maximális használatát.

Az egyidejűségi futtatókörnyezet alapértelmezett ütemezőt biztosít, így nem kell kezelnie az infrastruktúra részleteit. Az alkalmazás minőségi igényeinek kielégítése érdekében azonban saját ütemezési szabályzatot is megadhat, vagy adott ütemezőket társíthat adott tevékenységekhez.

A Feladatütemezőről további információt a Feladatütemezőben talál.

Resource Manager

A Resource Manager feladata a számítási erőforrások, például a processzorok és a memória kezelése. A Resource Manager a számítási feladatok futásidejű változásaira úgy válaszol, hogy erőforrásokat rendel hozzájuk, ahol azok a leghatékonyabbak lehetnek.

A Resource Manager absztrakcióként szolgál a számítási erőforrások felett, és elsősorban a Feladatütemezővel kommunikál. Bár a Resource Managerrel finomhangolhatja a kódtárak és alkalmazások teljesítményét, általában a párhuzamos minták tára, az ügynökök tára és a feladatütemező által biztosított funkciókat használja. Ezek a tárak a Resource Manager használatával dinamikusan újraegyensúlyozják az erőforrásokat a számítási feladatok változásakor.

[Felső]

C++ Lambda-kifejezések

Az egyidejűségi futtatókörnyezet által definiált számos típus és algoritmus C++ sablonként van implementálva. Néhány ilyen típus és algoritmus paraméterként olyan rutint vesz igénybe, amely elvégzi a munkát. Ez a paraméter lehet lambda függvény, függvényobjektum vagy függvénymutató. Ezeket az entitásokat munkafüggvényeknek vagy munkahelyi rutinoknak is nevezik.

A Lambda-kifejezések egy fontos új Visual C++ nyelvi funkció, mivel tömör módot biztosítanak a párhuzamos feldolgozáshoz szükséges munkafüggvények definiálására. A függvényobjektumok és a függvénymutatók lehetővé teszik az egyidejűségi futtatókörnyezet használatát a meglévő kóddal. Javasoljuk azonban, hogy az általuk biztosított biztonsági és hatékonysági előnyök miatt használjon lambdakifejezéseket új kód írásakor.

Az alábbi példa a lambdafüggvények, függvényobjektumok és függvénymutatók szintaxisának összehasonlítását mutatja be a concurrency::parallel_for_each algoritmus többszöri hívásán keresztül. Minden hívás parallel_for_each más technikával számítja ki az std::array objektum egyes elemeinek négyzetét.

// comparing-work-functions.cpp
// compile with: /EHsc
#include <ppl.h>
#include <array>
#include <iostream>

using namespace concurrency;
using namespace std;

// Function object (functor) class that computes the square of its input.
template<class Ty>
class SquareFunctor
{
public:
   void operator()(Ty& n) const
   {
      n *= n;
   }
};

// Function that computes the square of its input.
template<class Ty>
void square_function(Ty& n)
{
   n *= n;
}

int wmain()
{
   // Create an array object that contains 5 values.
   array<int, 5> values = { 1, 2, 3, 4, 5 };

   // Use a lambda function, a function object, and a function pointer to 
   // compute the square of each element of the array in parallel.

   // Use a lambda function to square each element.
   parallel_for_each(begin(values), end(values), [](int& n){n *= n;});

   // Use a function object (functor) to square each element.
   parallel_for_each(begin(values), end(values), SquareFunctor<int>());

   // Use a function pointer to square each element.
   parallel_for_each(begin(values), end(values), &square_function<int>);

   // Print each element of the array to the console.
   for_each(begin(values), end(values), [](int& n) { 
      wcout << n << endl;
   });
}

Kimenet

1
256
6561
65536
390625

További információ a Lambda függvényekről a C++-ban: Lambda Expressions.

[Felső]

Követelmények

Az alábbi táblázat az egyidejűségi futtatókörnyezet egyes összetevőihez társított fejlécfájlokat mutatja be:

Összetevő Fejlécfájlok
Párhuzamos minták kódtára (PPL) ppl.h

concurrent_queue.h

concurrent_vector.h
Aszinkron ügynökök könyvtára agents.h
Feladatütemező concrt.h
Resource Manager concrtrm.h

Az egyidejűségi futtatókörnyezet deklarálva van az Egyidejűség névtérben. (Használhat egyidejűséget is, amely a névtér aliasa.) A concurrency::details névtér támogatja a Concurrency Runtime keretrendszert, és nem közvetlenül a kódból való használatra szolgál.

Az egyidejűségi futtatókörnyezet a C futtatókörnyezeti kódtár (CRT) részeként érhető el. A CRT-t használó alkalmazások készítéséről további információt a CRT-kódtár funkciói című témakörben talál.

[Felső]