Aracılığıyla paylaş


Nasıl yapılır: bir iletiyi engelleme filtresi kullanma

Bu belge, kabul etmek veya reddetmek o iletinin yükü üzerinde bir ileti için bir zaman uyumsuz ileti bloğu etkinleştirmek için bir filtre işlevini kullanın gösterilmiştir.

Oluştururken ileti bloğu nesnesi gibi bir concurrency::unbounded_buffer, bir concurrency::call, ya da bir concurrency::transformer, sizin verdiğiniz bir filtresi işlevini ileti bloğu kabul veya reddeder bir ileti olup olmadığını belirler. Filter işlevi, ileti bloğu yalnızca belirli değerleri alır güvence altına almak için kullanışlı bir yoldur.

Filtre fonksiyonları ileti blokları formuna bağlama etkinleştirmek için önemli dataflow ağlar. Dataflow ağda belirli ölçütlere uyan iletileri işleyerek ileti blokları veri akışını denetler. Bu veri akışının denetim yapıları, döngüler, koşullu deyimleri gibi kullanarak burada düzenlenen akış denetimi modeli karşılaştırın ve benzeri.

Bu belge, İleti Filtresi nasıl temel bir örnek sağlar. İleti filtreler ve dataflow modeli ileti blokları bağlanacak ek örnekler için bkz: İzlenecek yol: Dataflow Aracısı oluşturma ve İzlenecek yol: görüntü işleme ağ oluşturma.

Örnek

Aşağıdaki işlevi göz önünde count_primes, gelen iletilere filtre bir ileti bloğu temel kullanımını göstermektedir. Asal sayıların ileti bloğu ekler bir std::vector nesnesi. count_primes İşlevi birkaç numaraları ileti bloğu gönderir ileti bloğu çıkış değerleri alır ve bu sayılar asal konsola yazdırır.

// 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 Nesnesini işler tüm giriş değerleri; Ancak, asal olan değerleri gerektirir. Uygulamanın iletiyi gönderenin asal sayıların gönderir, yazılmış olsa da, ileti alıcı gereksinimleri her zaman bilinen olamaz.

Aşağıdaki işlev count_primes_filter, aynı görevi olarak gerçekleştiren count_primes işlevi. Ancak, transformer bu nesne asal olan değerleri kabul etmek için bir filtre işlevi kullanır. Eylem gerçekleştirir işlevi yalnızca asal sayıların alır; Bu nedenle, aranacak yok is_prime işlevi.

Çünkü transformer nesnesi alır asal sayıların yalnızca transformer nesnesinin kendisi asal sayıların basılı tutun. Diğer bir deyişle, transformer Bu örnekte nesnenin asal sayıların eklemek için gerekli değil vector nesnesi.

// 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 Nesnesini asal olan değerleri şimdi işler. Önceki örnekte, transformer nesnesini tüm iletileri işler. Bu nedenle, önceki örnekte aynı sayıda gönderdiği iletileri alması gerekir. Bu örnek sonucunu kullanır concurrency::send almak için kaç iletileri belirlemek için işlev transformer nesnesi. send İşlevini verir true , ileti arabelleği iletiyi kabul eder ve false , ileti arabelleği iletiyi reddeder. Bu nedenle, ileti arabelleği ileti kabul sayısı asal sayıların sayısı ile eşleşir.

Örneğin aşağıdaki kodu gösterilir. Her ikisi de örnek çağrı count_primes işlevi ve count_primes_filter işlevi.

// 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
    */
}

Bu örnek aşağıdaki çıktıyı üretir:

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

Kod Derleniyor

Örnek kodu kopyalayın ve Visual Studio Project'te yapıştırın veya adlı bir dosyaya yapıştırın primes filter.cpp ve Visual Studio komut istemi penceresinde aşağıdaki komutu çalıştırın.

cl.exe /EHsc primes-filter.cpp

Güçlü Programlama

Filter işlevi, lambda işlevi, işlev işaretçisi veya işlevi nesnesi olabilir. Her filtre işlevi aşağıdaki biçimlerden birini alır:

bool (_Type)
bool (_Type const &)

Gereksiz veri kopyalama kurtulmak için değer iletilen bir toplama türü varsa, ikinci formu kullanın.

Ayrıca bkz.

Görevler

İzlenecek yol: Dataflow Aracısı oluşturma

İzlenecek yol: görüntü işleme ağ oluşturma

Başvuru

Transformer sınıfı

Kavramlar

Zaman uyumsuz aracıları kitaplığı