LabVIEW의 생산자/소비자 아키텍처

개요

생산자/소비자 디자인 패턴은 마스터/슬레이브 디자인 패턴에 기반을 두고 있으며, 이 패턴을 사용하면 서로 다른 속도로 실행되는 여러 루프 간의 데이터 공유가 보다 원활해집니다. 생산자/소비자 패턴은 서로 다른 속도로 데이터를 생성하고 사용하는 프로세스를 분리하는 데 사용됩니다. 생산자/소비자 디자인 패턴의 병렬 루프는 두 가지 범주로 분류되는데, 하나는 데이터를 생성하는 루프이고 다른 하나는 생성된 데이터를 사용하는 루프입니다.

이 문서에서는 생산자/소비자 아키텍처의 일반적인 사용 사례와 이점에 대해 설명하고 LabVIEW에서 이 기술을 사용하는 방법을 설명하는 리소스를 소개합니다. 루프 간의 정보 공유에 대한 보다 심층적인 내용이나 LabVIEW에서 생산자/소비자 루프를 만드는 단계별 가이드와 연습 문제를 보려면 LabVIEW Core 2 과정을 수강하십시오.

내용

왜 생산자/소비자 패턴을 사용해야 합니까?

생산자/소비자 패턴을 사용하면 개별 속도로 반복하면서 동시에 여러 프로세스를 쉽게 처리할 수 있습니다.

버퍼링된 통신

서로 다른 속도로 실행되는 프로세스가 여러 개인 경우 프로세스 간의 통신 버퍼링이 가능하다면 매우 유용합니다. 버퍼가 충분히 크면 생산자 루프가 데이터 손실 없이 소비자 루프보다 훨씬 빠른 속도로 실행될 수 있습니다.
예를 들어 두 개의 프로세스가 있는 어플리케이션을 생각해 봅니다. 첫 번째 프로세스는 데이터 수집을 수행하고, 두 번째 프로세스는 데이터를 가져와서 네트워크로 전송합니다. 첫 번째 프로세스는 두 번째 프로세스의 세 배 속도로 작동합니다. 이 어플리케이션을 구현하는 데 생산자/소비자 디자인 패턴을 사용할 경우 데이터 수집 프로세스는 생산자가 되고 네트워크는 소비자를 처리합니다. 대규모 통신 큐(버퍼)가 있으면 네트워크 프로세스는 데이터 수집 루프가 수집하는 많은 양의 데이터에 액세스할 수 있습니다. 데이터를 버퍼링하는 이 기능은 데이터 손실을 최소화합니다.

큐(Queue) 함수를 사용할 때 발생하는 버퍼링된 통신을 시각화하려면 생산자/소비자 루프를 사용하여 LabVIEW 윈도우 이동 예제 프로그램을 참조하십시오.

데이터 수집 및 처리

생산자/소비자 패턴은 일반적으로 순서대로 여러 데이터 세트를 수집하여 처리할 때 사용됩니다.
데이터를 수락하고, 받은 순서대로 데이터를 처리하는 어플리케이션을 작성한다고 가정해봅시다. 이 데이터를 큐에 추가(생산)하는 것이 실제 처리(소비)하는 것보다 훨씬 빠르므로 이 어플리케이션에는 생산자/소비자 디자인 패턴이 가장 적합합니다. 이렇게 하면 소비자 루프가 자신의 속도로 데이터를 처리하면서 생산자 루프는 계속해서 데이터를 큐에 추가할 수 있습니다.

생산자와 소비자가 이 어플리케이션의 동일한 루프에 있는 경우 데이터 처리 속도와 일치하도록 데이터 수집 속도가 느려진다는 점을 고려하십시오. 따라서 프로세스, 데이터 수집(생산자) 및 처리(소비자)로 코드를 나누는 것이 좋습니다. 

네트워크 통신

네트워크 통신에서는 두 프로세스가 동시에 서로 다른 속도로 작동해야 합니다. 첫 번째 프로세스는 네트워크 회선을 지속적으로 폴링하여 패킷을 받고 두 번째 프로세스는 첫 번째 프로세스에서 받은 패킷을 가져와 분석합니다. 이 예제에서 첫 번째 프로세스는 두 번째 프로세스에 데이터를 제공하므로 생산자에 해당하고, 두 번째 프로세스는 소비자가 됩니다. 이 어플리케이션은 생산자/소비자 디자인 패턴을 사용하면 도움이 됩니다. 생산자 및 소비자 병렬 루프는 네트워크로부터 데이터를 가져와서 분석하고, 두 루프 사이의 큐 통신을 통해 가져온 네트워크 패킷을 버퍼링합니다. 이 버퍼링은 네트워크 통신의 사용량이 많을 때 매우 중요하게 됩니다. 버퍼링을 사용하면 분석 속도보다 더 빠르게 패킷을 가져와서 통신할 수 있습니다.

큐 메시지 처리

큐 메시지 핸들러 아키텍처는 특수한 버전의 생산자/소비자 아키텍처입니다. 생산자/소비자 디자인 패턴의 루프 간 데이터 통신에는 데이터 큐가 사용됩니다. 이러한 큐는 생산자 및 소비자 루프 간에 데이터 버퍼링의 이점을 제공합니다.

생산자/소비자 빌드

생산자/소비자 디자인은 생산자 및 소비자라는 두 개의 범주로 분류되는 병렬 루프로 구성됩니다. 생산자 루프와 소비자 루프 간의 통신은 또는 채널 와이어를 사용하여 수행됩니다.

LabVIEW에는 함수 팔레트 >> 데이터 통신 >> 큐 작업에 큐 작업 VI가 내장되어 있습니다.

큐는 FIFO 이론을 기반으로 합니다. 생산자/소비자 디자인 패턴에서는 생산자 및 소비자 루프 외부에서 큐를 초기화할 수 있습니다. 생산자 루프는 소비자 루프를 위한 데이터를 생성하므로 큐에 데이터를 추가합니다(큐에 데이터를 넣는 것을 "큐에 추가"라고 함).

소비자 루프는 해당 큐에서 데이터를 제거합니다(큐에서 데이터를 제거하는 것을 "큐에서 제거"라고 함). 큐는 FIFO 방식이므로 소비자는 항상 생산자가 큐에 넣은 순서대로 데이터를 분석합니다. 그림 1은 LabVIEW에서 생산자/소비자 디자인 패턴을 만드는 방법을 보여줍니다.


그림 1: 생산자/소비자 디자인 패턴

참고: 이 이미지는 프로젝트에서 재사용할 수 있는 LabVIEW 코드를 포함한 LabVIEW 스니펫입니다. 스니펫을 사용하려면 이미지를 마우스 오른쪽 버튼으로 클릭하고 컴퓨터에 저장한 후 이미지 파일을 LabVIEW 다이어그램으로 끌어서 놓으십시오. 


어플리케이션의 시작점으로 사용할 수 있는 LabVIEW 내의 큐를 사용하는 예제가 있습니다. LabVIEW 예제 탐색기를 사용하여 예제를 찾고 Queue(큐)를 검색하십시오.

채널

채널 와이어 기능은 LabVIEW 2016에 추가되었습니다. 채널 와이어를 사용하면 큐와 똑같은 기능을 수행하도록 할 수 있습니다.

큐에서는, 큐 참조를 설정하고(큐 얻기) 데이터를 추가하고(큐에 추가) 데이터를 제거하고(큐에서 제거) 큐 참조를 닫습니다(큐 해제). 채널을 사용하면 간단하게 데이터의 발신자와 수신자만 설정하면 됩니다.

채널 와이어와 시작하기 템플릿에 관한 자세한 정보는 채널 와이어를 사용하여 코드의 병렬 섹션 간 데이터 통신 수행 – LabVIEW 도움말을 참조하십시오.

중요 참고사항

큐 사용, 동기화 등과 같이 생산자/소비자 디자인 패턴을 다룰 때 주의해야 하는 몇 가지 사항이 있습니다.

큐 사용

문제: 큐는 하나의 특정 데이터 타입에 연동됩니다. 따라서 생산자 루프에서 생성된 각 데이터 아이템을 다른 큐에 넣어야 합니다. 이 요구사항 때문에 블록다이어그램이 상당히 복잡해지므로 문제가 될 수 있습니다.
해결책: 큐는 배열 및 클러스터와 같은 데이터 타입을 수용할 수 있습니다. 각 데이터 아이템을 클러스터 안에 배치할 수 있습니다. 이렇게 하면 클러스터 데이터 타입 뒤에 다양한 데이터 타입이 마스킹됩니다. 그림 1은 통신 큐를 사용하여 클러스터 데이터 타입을 구현합니다.

동기화

문제: 생산자/소비자 디자인 패턴은 동기화를 기반으로 하지 않으므로 루프의 초기 실행이 특정 순서를 따르지 않습니다.  따라서 한 루프를 다른 루프보다 먼저 초기화하면 문제가 발생할 수 있습니다.

해결책: 생산자/소비자 디자인 패턴에 이벤트 구조를 추가하면 이러한 유형의 동기화 문제를 해결할 수 있습니다.  그림 2는 이 기능을 구현하기 위한 템플릿을 보여줍니다.  동기화 함수와 관련된 자세한 정보는 아래의 관련 링크 섹션에 있습니다.


그림 2: 생산자/소비자 디자인 패턴에 이벤트 구조 사용

 참고: 이 이미지는 프로젝트에서 재사용할 수 있는 LabVIEW 코드를 포함한 LabVIEW 스니펫입니다. 스니펫을 사용하려면 이미지를 마우스 오른쪽 버튼으로 클릭하고 컴퓨터에 저장한 후 이미지 파일을 LabVIEW 다이어그램으로 끌어서 놓으십시오.