다음을 통해 공유


방법: 메시지 블록 필터 사용

이 문서에서는 필터 함수를 사용하여 비동기 메시지 블록에서 해당 메시지의 페이로드를 기준으로 메시지를 수락하거나 거부할 수 있도록 설정하는 방법을 보여 줍니다.

만들면 메시지 블록 개체 같은 concurrency::unbounded_buffera concurrency::call, 또는 concurrency::transformer, 제공할 수는 필터 함수 메시지 블록 수락 또는 거부 메시지 여부 결정.필터 함수는 메시지 블록이 특정 값만 받을 수 있게 하는 유용한 방법입니다.

필터 함수는 이 함수를 통해 메시지 블록을 연결하여 데이터 흐름 네트워크를 구성할 수 있으므로 중요합니다.데이터 흐름 네트워크에서 메시지 블록은 특정 조건에 맞는 메시지만 처리하여 데이터 흐름을 제어합니다.데이터 흐름이 조건문, 루프 등의 제어 구조를 사용하여 조정되는 제어 흐름 모델과 이 네트워크를 비교할 수 있습니다.

이 문서에서는 메시지 필터를 사용하는 방법에 대한 기본 예제를 제공합니다.메시지 필터 및 데이터 흐름 모델을 사용하여 메시지 블록을 연결하는 추가 예제를 보려면 연습: 사용자 지정 데이터 흐름 에이전트 만들기연습: 이미지 처리 네트워크 만들기를 참조하십시오.

예제

들어오는 메시지를 필터링하지 않는 메시지 블록의 기본 사용법을 보여 주는 count_primes 함수를 살펴봅니다.이 메시지 블록은 std::vector 개체에 소수를 추가합니다.count_primes 함수는 여러 개의 숫자를 메시지 블록으로 보내고, 메시지 블록에서 출력 값을 받고, 소수를 콘솔에 출력합니다.

// 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 개체는 모든 입력 값을 처리하지만 이 개체에는 소수 값만 필요합니다.메시지 전송자가 소수만 보내도록 응용 프로그램을 작성할 수 있지만 메시지 수신자의 요구 사항을 항상 알 수 있는 것은 아닙니다.

count_primes_filter 함수는 count_primes 함수와 동일한 작업을 수행합니다.그러나 이 버전에서 transformer 개체는 필터 함수를 사용하여 소수 값만 받아들입니다.작업을 수행하는 함수는 소수만 받으므로 is_prime 함수를 호출할 필요가 없습니다.

transformer 개체는 소수만 받아들이므로 transformer 개체 자체에서 소수를 포함할 수 있습니다.즉, 이 예제의 transformer 개체는 vector 개체에 소수를 추가할 필요가 없습니다.

// 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 개체는 소수 값만 처리합니다.앞의 예제에서는 transformer 개체가 모든 메시지를 처리합니다.따라서 앞의 예제에서는 보내는 메시지와 동일한 수의 메시지를 받아야 합니다.이 예제 결과를 사용 하는 concurrency::send 함수에서 수신 메시지를 확인 하는 transformer 개체입니다.send 함수는 메시지 버퍼가 메시지를 수락할 때 true를 반환하고 메시지를 거부할 때 false를 반환합니다.따라서 메시지 버퍼가 메시지를 수락하는 횟수와 소수 개수는 일치합니다.

다음 코드에서는 전체 예제를 보여 줍니다.이 예제에서는 count_primes 함수와 count_primes_filter 함수를 호출합니다.

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

이 예제의 결과는 다음과 같습니다.

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

코드 컴파일

예제 코드를 복사 하 고 Visual Studio 프로젝트에 붙여 또는 라는 파일에 붙여 프라임 filter.cpp 및 다음 Visual Studio 명령 프롬프트 창에서 다음 명령을 실행 합니다.

cl.exe /EHsc primes-filter.cpp

강력한 프로그래밍

필터 함수는 람다 함수, 함수 포인터 또는 함수 개체가 될 수 있습니다.모든 필터 함수는 다음 형식 중 하나로 지정할 수 있습니다.

bool (_Type)
bool (_Type const &)

불필요하게 데이터를 복사하는 일이 없도록 하려면 값으로 전송되는 집계 형식인 경우 두 번째 형식을 사용합니다.

참고 항목

작업

연습: 사용자 지정 데이터 흐름 에이전트 만들기

연습: 이미지 처리 네트워크 만들기

참조

transformer 클래스

개념

비동기 에이전트 라이브러리