방법: 메시지 블록 필터 사용
이 문서에서는 필터 함수를 사용하여 비동기 메시지 블록에서 해당 메시지의 페이로드를 기준으로 메시지를 수락하거나 거부할 수 있도록 설정하는 방법을 보여 줍니다.
만들면 메시지 블록 개체 같은 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 &)
불필요하게 데이터를 복사하는 일이 없도록 하려면 값으로 전송되는 집계 형식인 경우 두 번째 형식을 사용합니다.