Cara: Menggunakan Filter Blok Pesan

Dokumen ini menunjukkan cara menggunakan fungsi filter untuk mengaktifkan blok pesan asinkron untuk menerima atau menolak pesan berdasarkan payload pesan tersebut.

Saat Anda membuat objek blok pesan seperti konkurensi::unbounded_buffer, konkurensi::panggilan, atau konkurensi::transformer, Anda dapat menyediakan fungsi filter yang menentukan apakah blok pesan menerima atau menolak pesan. Fungsi filter adalah cara yang berguna untuk menjamin bahwa blok pesan hanya menerima nilai tertentu.

Fungsi filter penting karena memungkinkan Anda menyambungkan blok pesan untuk membentuk jaringan aliran data. Dalam jaringan aliran data, blok pesan mengontrol aliran data dengan hanya memproses pesan yang memenuhi kriteria tertentu. Bandingkan ini dengan model aliran kontrol, di mana aliran data diatur dengan menggunakan struktur kontrol seperti pernyataan kondisional, perulangan, dan sebagainya.

Dokumen ini menyediakan contoh dasar tentang cara menggunakan filter pesan. Untuk contoh tambahan yang menggunakan filter pesan dan model aliran data untuk menyambungkan blok pesan, lihat Panduan: Membuat Agen Aliran Data dan Panduan: Membuat Jaringan Pemrosesan Gambar.

Contoh: fungsi count_primes

Pertimbangkan fungsi berikut, count_primes, yang mengilustrasikan penggunaan dasar blok pesan yang tidak memfilter pesan masuk. Blok pesan menambahkan nomor prima ke objek std::vector . Fungsi ini count_primes mengirim beberapa angka ke blok pesan, menerima nilai output dari blok pesan, dan mencetak angka-angka yang prima ke konsol.

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

Objek transformer memproses semua nilai input; namun, hanya memerlukan nilai-nilai yang prima. Meskipun aplikasi dapat ditulis sehingga pengirim pesan hanya mengirim nomor utama, persyaratan penerima pesan tidak selalu dapat diketahui.

Contoh: fungsi count_primes_filter

Fungsi berikut, count_primes_filter, melakukan tugas yang sama dengan count_primes fungsi . Namun, transformer objek dalam versi ini menggunakan fungsi filter untuk hanya menerima nilai-nilai yang prima. Fungsi yang melakukan tindakan hanya menerima angka utama; oleh karena itu, tidak perlu memanggil is_prime fungsi .

transformer Karena objek hanya menerima bilangan prima, objek itu transformer sendiri dapat menampung angka utama. Dengan kata lain, transformer objek dalam contoh ini tidak diperlukan untuk menambahkan bilangan prima ke vector objek.

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

Objek transformer sekarang hanya memproses nilai-nilai yang prima. Dalam contoh sebelumnya, transformer objek memproses semua pesan. Oleh karena itu, contoh sebelumnya harus menerima jumlah pesan yang sama dengan yang dikirimnya. Contoh ini menggunakan hasil konkurensi::kirim fungsi untuk menentukan berapa banyak pesan yang akan diterima dari transformer objek. Fungsi send mengembalikan true ketika buffer pesan menerima pesan dan false ketika buffer pesan menolak pesan. Oleh karena itu, berapa kali buffer pesan menerima pesan cocok dengan jumlah angka utama.

Contoh: Sampel kode filter blok pesan selesai

Kode berikut menunjukkan contoh lengkapnya. Contoh memanggil count_primes fungsi dan count_primes_filter fungsi .

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

Mengompilasi Kode

Salin kode contoh dan tempelkan dalam proyek Visual Studio, atau tempelkan dalam file yang diberi nama primes-filter.cpp lalu jalankan perintah berikut di jendela Prompt Perintah Visual Studio.

cl.exe /EHsc primes-filter.cpp

Pemrograman yang Kuat

Fungsi filter dapat berupa fungsi lambda, penunjuk fungsi, atau objek fungsi. Setiap fungsi filter mengambil salah satu formulir berikut:

bool (T)
bool (T const &)

Untuk menghilangkan penyalinan data yang tidak perlu, gunakan formulir kedua saat Anda memiliki jenis agregat yang ditransmisikan oleh nilai.

Baca juga

Pustaka Agen Asinkron
Panduan: Membuat Agen Aliran Data
Panduan: Membuat Jaringan Pemrosesan Gambar
Kelas transformator