Nasıl yapılır: İleti Bloğu Filtresini Kullanma

Bu belgede, zaman uyumsuz bir ileti bloğunun iletinin yükü temelinde bir iletiyi kabul etmesi veya reddetmesi için filtre işlevinin nasıl kullanılacağı gösterilmektedir.

Eşzamanlılık::unbounded_buffer, eşzamanlılık::çağrı veya eşzamanlılık::transformer gibi bir ileti bloğu nesnesi oluşturduğunuzda, ileti bloğunun iletiyi kabul edip etmediğini belirleyen bir filtre işlevi sağlayabilirsiniz. Filtre işlevi, ileti bloğunun yalnızca belirli değerleri almasını garanti etmenin kullanışlı bir yoludur.

Filtre işlevleri, ileti bloklarını veri akışı ağlarına bağlamanıza olanak sağladığından önemlidir. Veri akışı ağında, ileti blokları yalnızca belirli ölçütlere uyan iletileri işleyerek veri akışını denetler. Bunu, koşullu deyimler, döngüler vb. denetim yapıları kullanılarak veri akışının düzenlendiği denetim akışı modeliyle karşılaştırın.

Bu belge, ileti filtresinin nasıl kullanılacağına yönelik temel bir örnek sağlar. İleti bloklarını bağlamak için ileti filtrelerini ve veri akışı modelini kullanan ek örnekler için bkz . İzlenecek Yol: Veri Akışı Aracısı Oluşturma ve İzlenecek Yol: Görüntü İşleme Ağı Oluşturma.

Örnek: count_primes işlevi

Gelen iletileri filtrelemeyen bir ileti bloğunun temel kullanımını gösteren aşağıdaki işlevini count_primesgöz önünde bulundurun. İleti bloğu, asal sayıları std ::vector nesnesine ekler. count_primes İşlev, ileti bloğuna birkaç sayı gönderir, ileti bloğundan çıkış değerlerini alır ve konsola asal sayıları 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 Nesnesi tüm giriş değerlerini işler; ancak yalnızca asal değerleri gerektirir. Uygulama, ileti gönderenin yalnızca asal sayılar göndermesi için yazılabilir, ancak ileti alıcısının gereksinimleri her zaman bilinmez.

Örnek: count_primes_filter işlevi

Aşağıdaki işlevi, count_primes_filterişleviyle aynı görevi count_primes gerçekleştirir. Ancak, bu sürümdeki transformer nesne, yalnızca asal değerleri kabul etmek için bir filtre işlevi kullanır. Eylemi gerçekleştiren işlev yalnızca asal sayılar alır; bu nedenle işlevini çağırması is_prime gerekmez.

transformer Nesne yalnızca asal sayılar aldığından, nesnenin transformer kendisi asal sayıları tutabilir. Başka bir deyişle, bu örnekteki transformer nesnenin nesneye asal sayıları eklemek için vector gerekli değildir.

// 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 Nesnesi artık yalnızca asal değerleri işler. Önceki örnekte, transformer nesne tüm iletileri işler. Bu nedenle, önceki örnek gönderdiği ileti sayısıyla aynı sayıda ileti almalıdır. Bu örnekte, nesneden kaç ileti alındığını belirlemek için concurrency::send işlevinin transformer sonucu kullanılır. İşlev, send ileti arabelleği iletiyi kabul ettiğinde ve false ileti arabelleği iletiyi reddettiğinde döndürürtrue. Bu nedenle, ileti arabelleğinin iletiyi kabul etme sayısı, asal sayıların sayısıyla eşleşir.

Örnek: İleti bloğu filtre kodu örneği tamamlandı

Aşağıdaki kod, tam örneği gösterir. Örnek hem işlevi hem de count_primes işlevi count_primes_filter çağırır.

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

Kod Derleniyor

Örnek kodu kopyalayıp bir Visual Studio projesine yapıştırın veya adlı primes-filter.cpp bir dosyaya yapıştırın ve ardından bir Visual Studio Komut İstemi penceresinde aşağıdaki komutu çalıştırın.

cl.exe /EHsc primes-filter.cpp

Güçlü Programlama

Filtre işlevi bir lambda işlevi, işlev işaretçisi veya işlev nesnesi olabilir. Her filtre işlevi aşağıdaki formlardan birini alır:

bool (T)
bool (T const &)

Gereksiz veri kopyalamayı ortadan kaldırmak için, değerle iletilen bir toplama türünüz olduğunda ikinci formu kullanın.

Ayrıca bkz.

Zaman Uyumsuz Aracılar Kitaplığı
İzlenecek Yol: Veri Akışı Aracısı Oluşturma
İzlenecek yol: Görüntü İşleme Ağı Oluşturma
transformer Sınıfı