Udostępnij za pośrednictwem


Jak: Filtr bloku komunikatu

Ten dokument demonstruje, jak użyć funkcji filtru, aby włączyć blok asynchroniczny komunikat o zaakceptowanie lub odrzucenie wiadomości w oparciu o ładunku tej wiadomości.

Podczas tworzenia obiektu bloku komunikatu takich jak concurrency::unbounded_buffer, concurrency::call, lub concurrency::transformer, może dostarczyć funkcji filtru Określa, czy blok komunikatów akceptuje lub odrzuca wiadomość.Funkcja filtr jest przydatny sposób, aby zagwarantować, że blok wiadomości odbiera tylko niektóre wartości.

Funkcje filtrowania są ważne, ponieważ umożliwiają one połączyć bloków komunikatów w formie przepływ danych sieci.W sieci przepływ danych bloków komunikatów sterowania przepływem danych przez przetwarzanie tylko tych wiadomości, które spełniają określone kryteria.Porównanie to model kontroli przepływu, jeżeli przepływ danych jest regulowana przy użyciu struktur sterujących, takich jak instrukcje warunkowe pętli, i tak dalej.

Niniejszy dokument zawiera prosty przykład zastosowania filtru wiadomości.Dodatkowe przykłady, używające filtry wiadomości i model przepływ danych do łączenia się bloki wiadomości, zobacz Instruktaż: Tworzenie agenta przepływ danych i Instruktaż: Tworzenie sieci przetwarzania obrazu.

Przykład

Należy rozważyć następującą funkcję count_primes, który ilustruje wykorzystanie podstawowych bloku komunikatu, który filtruje przychodzące wiadomości.Blok komunikatów dołącza liczb pierwszych do std::vector obiektu.count_primes Funkcji wysyła kilka numerów do bloku komunikatów, otrzymuje wartości wyjście z bloku komunikatów i wydrukuje 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 wartości, które są Premier.Chociaż aplikacji można zapisać tak, aby nadawcy wiadomości wysyła tylko liczby pierwsze, wymagania odbiorcy wiadomości nie zawsze są znane.

Następująca funkcja count_primes_filter, wykonuje to samo zadanie jako count_primes funkcji.Jednakże transformer obiekt w tej wersji używa funkcji filtru do akceptowania tylko wartości, które są Premier.Funkcja, która wykonuje akcję otrzymuje tylko liczby pierwsze; w związku z tym, nie mają wywoływać is_prime funkcji.

Ponieważ transformer obiekt odbiera tylko liczby pierwsze, transformer sam obiekt może zawierać liczby pierwsze.Innymi słowy transformer obiektu w tym przykładzie nie jest wymagane Aby dodać numery Premier 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 wynik concurrency::send funkcji, ile wiadomości od transformer obiektu.send Działać zwraca true kiedy bufor komunikatów akceptuje wiadomości i false kiedy bufor wiadomości odrzuca wiadomość.W związku z tym ile razy, że bufor komunikatów akceptuje wiadomości pasuje zliczania liczb pierwszych.

Poniższy kod przedstawia przykład kompletne.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
    */
}

Ten przykład generuje następujące wyniki:

Without filtering:
The following numbers are prime:
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 primes filter.cpp , a następnie uruchom następujące polecenie w oknie wiersza polecenia usługi programu Visual Studio.

cl.exe /EHsc primes-filter.cpp

Stabilne programowanie

Funkcja filtrowania może być funkcji lambda, wskaźnik funkcji lub obiekt funkcji.Każda funkcja filtru przyjmuje jedną z następujących form:

bool (_Type)
bool (_Type const &)

Aby wyeliminować zbędne kopiowanie danych, przy drugim formularzu Typ agregacji, przesyłane przez wartość.

Zobacz też

Zadania

Instruktaż: Tworzenie agenta przepływ danych

Instruktaż: Tworzenie sieci przetwarzania obrazu

Informacje

Transformator klasy

Koncepcje

Biblioteka agentów asynchroniczne