Udostępnij za pośrednictwem


Porady: korzystanie z filtra bloku komunikatów

Ten dokument pokazuje, jak użyć funkcji filtru, aby włączyć bloku asynchroniczny komunikat o zaakceptowanie lub odrzucenie wiadomości na podstawie ładunek tej wiadomości.

Podczas tworzenia obiektu bloku komunikatu takich jak concurrency::unbounded_buffer, concurrency::call, lub concurrency::transformer, może dostarczyć Funkcja filter Określa, czy blok wiadomości akceptuje lub odrzuca wiadomość.Funkcja filter jest przydatnym sposobem zagwarantowania, że bloku komunikatów otrzymuje tylko niektóre wartości.

Funkcje filtrowania są ważne, ponieważ umożliwiają one łączenie bloków komunikatów do formularza Przepływ danych sieci.W przypadku sieci przepływ danych bloków komunikatów sterowania przepływem danych przez przetwarzanie tylko te wiadomości, które spełniają określone kryteria.Porównać do modelu przepływ sterowania, gdzie przepływ danych jest regulowany za pomocą struktur sterujących, takich jak instrukcje warunkowe, pętli i tak dalej.

Niniejszy dokument zawiera prosty przykład użycia filtru komunikatów.Dodatkowe przykłady używające filtrów wiadomości i model przepływ danych do łączenia bloków komunikatów, zobacz Wskazówki: tworzenie agenta przepływu danych i Wskazówki: tworzenie sieci przetwarzania obrazów.

Przykład

Należy wziąć pod uwagę następujące funkcja, count_primes, który ilustruje wykorzystanie podstawowych bloku komunikatu, który nie filtruje przychodzące wiadomości.Bloku komunikatów dołącza liczb do std::vector obiektu.count_primes Funkcja wysyła kilka numerów do bloku komunikatów, odbiera wartości produkcji od bloku komunikatów i drukuje te numery, które są Premier do konsoli.

// Illustrates usage of a message buffer that does not use filtering. 
void count_primes(unsigned long random_seed)
{
    // Holds prime numbers.
    vector<unsigned long> primes;

    // Adds numbers that are prime to the vector object.
    transformer<unsigned long, unsigned long> t([&primes](unsigned long n) -> unsigned long
    {
        if (is_prime(n))
        {
            primes.push_back(n);
        }
        return n;
    });

    // Send random values to the message buffer.
    mt19937 generator(random_seed);
    for (int i = 0; i < 20; ++i)
    {
        send(t, static_cast<unsigned long>(generator()%10000));
    }

    // Receive from the message buffer the same number of times 
    // to ensure that the message buffer has processed each message. 
    for (int i = 0; i < 20; ++i)
    {
        receive(t);
    }

    // Print the prime numbers to the console.
    wcout << L"The following numbers are prime: " << endl;
    for(unsigned long prime : primes)
    {
        wcout << prime << endl;
    }
}

transformer Obiektu przetwarza wszystkie wprowadzania wartości; wymaga jednak tylko te wartości, które są Premier.Chociaż aplikacji można zapisać tak, że nadawcy wiadomości wysyła tylko liczb, nie zawsze wiadomo wymagania odbiorcy wiadomości.

Poniższa funkcja count_primes_filter, wykonuje to samo zadanie jako count_primes funkcji.Jednakże transformer obiektu w tej wersji korzysta z funkcji filtru, aby akceptowało tylko wartości, które są Premier.Funkcja, która wykonuje akcję otrzymuje tylko liczby pierwsze; w związku z tym, nie ma do wywoływania is_prime funkcji.

Ponieważ transformer obiekt odbiera tylko liczby pierwsze, transformer sam obiekt może pomieścić te liczby pierwsze.Innymi słowy transformer obiekt w tym przykładzie nie jest wymagane Aby dodać liczb do vector obiektu.

// Illustrates usage of a message buffer that uses filtering. 
void count_primes_filter(unsigned long random_seed)
{
    // Accepts numbers that are prime.
    transformer<unsigned long, unsigned long> t([](unsigned long n) -> unsigned long
    {
        // The filter function guarantees that the input value is prime. 
        // Return the input value. 
        return n;
    },
    nullptr,
    [](unsigned long n) -> bool
    {
        // Filter only values that are prime. 
        return is_prime(n);
    });

    // Send random values to the message buffer.
    mt19937 generator(random_seed);
    size_t prime_count = 0;
    for (int i = 0; i < 20; ++i)
    {
        if (send(t, static_cast<unsigned long>(generator()%10000)))
        {
            ++prime_count;
        }
    }

    // Print the prime numbers to the console. 
    wcout << L"The following numbers are prime: " << endl;
    while (prime_count-- > 0)
    {
        wcout << receive(t) << endl;
    }
}

transformer Obiektu teraz przetwarza tylko te wartości, które są Premier.W poprzednim przykładzie transformer obiektu przetwarza wszystkie wiadomości.W związku z tym poprzedni przykład musi otrzymać taką samą liczbę wiadomości, które wysyła.W tym przykładzie użyto wynik concurrency::send funkcja, aby określić, jak wiele komunikatów otrzymanych z transformer obiektu.send , Funkcja zwraca true kiedy bufor komunikatów akceptuje wiadomości i false kiedy bufor wiadomości odrzuci wiadomość.W związku z tym ile razy, że bufor komunikatów akceptuje wiadomości pasuje do zliczania liczb pierwszych.

Poniższy kod przedstawia przykład pełną.Przykład wywołuje zarówno count_primes funkcji i count_primes_filter funkcji.

// primes-filter.cpp 
// compile with: /EHsc
#include <agents.h>
#include <algorithm>
#include <iostream>
#include <random>

using namespace concurrency;
using namespace std;

// Determines whether the input value is prime. 
bool is_prime(unsigned long n)
{
    if (n < 2)
        return false;
    for (unsigned long i = 2; i < n; ++i)
    {
        if ((n % i) == 0)
            return false;
    }
    return true;
}

// Illustrates usage of a message buffer that does not use filtering. 
void count_primes(unsigned long random_seed)
{
    // Holds prime numbers.
    vector<unsigned long> primes;

    // Adds numbers that are prime to the vector object.
    transformer<unsigned long, unsigned long> t([&primes](unsigned long n) -> unsigned long
    {
        if (is_prime(n))
        {
            primes.push_back(n);
        }
        return n;
    });

    // Send random values to the message buffer.
    mt19937 generator(random_seed);
    for (int i = 0; i < 20; ++i)
    {
        send(t, static_cast<unsigned long>(generator()%10000));
    }

    // Receive from the message buffer the same number of times 
    // to ensure that the message buffer has processed each message. 
    for (int i = 0; i < 20; ++i)
    {
        receive(t);
    }

    // Print the prime numbers to the console.
    wcout << L"The following numbers are prime: " << endl;
    for(unsigned long prime : primes)
    {
        wcout << prime << endl;
    }
}

// Illustrates usage of a message buffer that uses filtering. 
void count_primes_filter(unsigned long random_seed)
{
    // Accepts numbers that are prime.
    transformer<unsigned long, unsigned long> t([](unsigned long n) -> unsigned long
    {
        // The filter function guarantees that the input value is prime. 
        // Return the input value. 
        return n;
    },
    nullptr,
    [](unsigned long n) -> bool
    {
        // Filter only values that are prime. 
        return is_prime(n);
    });

    // Send random values to the message buffer.
    mt19937 generator(random_seed);
    size_t prime_count = 0;
    for (int i = 0; i < 20; ++i)
    {
        if (send(t, static_cast<unsigned long>(generator()%10000)))
        {
            ++prime_count;
        }
    }

    // Print the prime numbers to the console. 
    wcout << L"The following numbers are prime: " << endl;
    while (prime_count-- > 0)
    {
        wcout << receive(t) << endl;
    }
}

int wmain()
{
    const unsigned long random_seed = 99714;

    wcout << L"Without filtering:" << endl;
    count_primes(random_seed);

    wcout << L"With filtering:" << endl;
    count_primes_filter(random_seed);

    /* Output:
    9973
    9349
    9241
    8893
    1297
    7127
    8647
    3229
    With filtering:
    The following numbers are prime:
    9973
    9349
    9241
    8893
    1297
    7127
    8647
    3229
    */
}

Kompilowanie kodu

Skopiuj przykładowy kod i wklej go w projekcie programu Visual Studio lub wkleić go w pliku o nazwie liczb pierwszych filter.cpp , a następnie uruchomić następujące polecenie w oknie wiersza polecenia programu Visual Studio.

cl.exe /EHsc primes-filter.cpp

Stabilne programowanie

Funkcja filter można funkcji lambda, wskaźnik funkcji lub obiekt funkcji.Każda funkcja Filtr przyjmuje jedną z następujących form:

  

Aby wyeliminować zbędne kopiowania danych, skorzystaj z drugiego formularza gdy masz typ agregatu, który jest przekazywany przez wartość.

Zobacz też

Zadania

Wskazówki: tworzenie agenta przepływu danych

Wskazówki: tworzenie sieci przetwarzania obrazów

Informacje

transformer — Klasa

Koncepcje

Biblioteka agentów asynchronicznych