2010-08-11 4 views
0

일종의 파이프 라인을 실행하는 펄 스크립트를 작성하고 있습니다. 먼저 여러 매개 변수가 포함 된 JSON 파일을 읽습니다. 그런 다음 몇 가지 작업을 수행합니다. 나중에 주로 필요한 데이터 구조를 작성하고 참조로 유지되는 출력 파일을 생성하는 외부 프로그램을 호출합니다.다중 스레드 및 스레드 간 데이터 공유로 perl 스크립트 설계

일반적으로이 단계마다 서브 루틴을 사용합니다. 이러한 각 서브 루틴은 보통 다른 서브 루틴이 쓰지 않는 고유 한 장소 (즉, 해시의 특정 키)에 데이터를 기록하고 다른 서브 루틴이 생성 한 데이터를 읽습니다.

이 단계는 순차적으로 수행하면 몇 분이 걸릴 수 있지만 대부분은 스레드 및 대기열을 사용하여 처리하는 방법을 알고있는 몇 가지 간단한 종속성 논리와 함께 병렬로 실행할 수 있습니다. 그래서 어떻게 스레드간에 데이터를 공유 할 수 있도록 이것을 구현해야하는지 궁금합니다. 프레임 워크를 어떻게 제안 하시겠습니까? 아마도 하나의 인스턴스 만 가질 객체를 사용하고 모든 공유 데이터를 $self에 보관 하시겠습니까? 아마도 일부 "전역"공유 변수가있는 간단한 스크립트 (개체 없음)가 있습니까? ...

나는 분명히 단순하고 깔끔한 솔루션을 선호합니다.

답변

3

threads::shared을 읽으십시오. 기본적으로 perl 변수는 공유되지 않습니다. 그러나 그들에 shared 속성을 배치하면됩니다. 당신이 그들에 대한 액세스를 동기화 할 경우 혼란이없는 것으로 생각되는, Thread::Queue을 사용하고,뿐만 아니라이 작업을 수행 할 수 그러나

my %repository: shared; 

그런 다음, 가장 쉬운 방법은

{ lock(%repository); 
    $repository{JSON_dump} = $json_dump; 
} 
# %respository will be unlocked at the end of scope. 

이다 :

$repo_queue->enqueue(JSON_dump => $json_dump); 

그런 다음 소비자 스레드는 단지 수 :

my ($key, $value) = $repo_queue->dequeue(2); 
$repository{ $key } = $value; 
+0

+1 Axeman에게 감사드립니다. (예를 들어'저장소 -> {키} ')가 변경되었을 때 전체 저장소를 잠글 필요가 있습니까? –

+0

@David B, 예, 불행히도, 그것은 http://search.cpan.org를 참조하십시오./perldoc? threads :: shared # lock_VARIABLE – Axeman

+0

"Perl 변수가 공유되지 않았습니다"어떤 취향에 따라 다르지 않습니다 http://perldoc.perl.org/Thread.html – Hawk

1

Perl에서 확실히 할 수 있습니다.이 매뉴얼 페이지는 Perl에서 스레드를 사용할 때 발생하는 방법과 함정을 가장 잘 설명하므로 perldoc threadsperldoc threads::shared을 참조하십시오.

Perl 모듈을 포함한 다양한 인터페이스를 가지고있는 Gearman과 같은 큐 관리 시스템을 사용할 수 있다면 실제로 사용할 것을 제안합니다. 이를 통해 원하는만큼 많은 "작업자"(실제 작업을 수행하는 잠수정)를 만들고 적절한 작업을 예약 한 다음 결과를 대조하는 간단한 "클라이언트"를 만들 수 있습니다. 해시 키를 특정 용도로 사용하지 않아도됩니다. 그런 일이나 일에.

이 접근법은 확장 성이 뛰어날뿐만 아니라 다른 시스템에 클라이언트와 작업자 (심지어 관리자)가있을 수 있습니다.

TheSchwartz와 같은 다른 대기열 시스템은 Gearman이 제공하는 피드백/결과가 없으므로 표시되지 않습니다. 모든 이펙트에서 Gearman을 사용하면이 방법은 설명 된 스레드 시스템과 거의 같습니다. 즉, 스레드를 기반으로하는 모든 시스템이 결국 변수를 잠그고, 세마포를 사용하고, 스레드를 결합해야하는 번거 로움과 두통이 없습니다.

+0

감사합니다. 내가 놓친 것은 스레드간에 정보를 공유하도록 제안하는 방법입니다. –

+0

David, http://search.cpan.org/~bradfitz/Gearman/lib/Gearman/Worker를 확인하십시오.pm – Octoberdan

+0

David, 접근 방식에 따라 다름 : threads와 함께 threads :: shared의 공유 변수를 사용하십시오. Gearman을 사용하면 변수를 공유하는 대신 "this, this and this other piece of data"와 같이 중요한 데이터를 작업자 스레드로 전달할 수 있습니다. 동일한 데이터 조각을 처리하기 위해 다른 subs가 필요한 경우 해당 데이터를 반환하도록합니다. – mfontani