2013-03-22 1 views
1

httpwebrequest을 사용하여 웹 서버에 액세스하고 주어진 페이지 범위에서 수천 개의 레코드를 가져 오려고합니다. 웹 페이지에 대한 각각의 히트는 15 개의 레코드를 가져 오며, 웹 서버에는 거의 8 ~ 10000 페이지가 있습니다. 즉, 서버에 총 120000 회의 조회가 발생했습니다! 단일 프로세스로 간단하게 수행하면 작업에 많은 시간이 소요될 수 있습니다. 따라서 다중 스레딩은 즉시 해결할 수있는 솔루션입니다.여러 스레드를 사용하여 웹 서버에서 효율적으로 검색

현재 검색 목적을 위해 작업자 클래스를 만들었습니다. 작업자 클래스는 지정된 범위에서 검색하기 위해 5 개의 하위 작업자 (스레드)를 생성합니다. 하지만, 초보자가 스레딩을 할 수있는 능력으로 인해, 나는 그것을 작동시키지 못합니다. 왜냐하면 나는 동기화가 잘되지 않아서 모든 일이 함께 이루어지기 때문입니다.

public void Start() 
{ 
    this.totalRangePerThread = ((this.endRange - this.startRange)/this.subWorkerThreads.Length); 
    for (int i = 0; i < this.subWorkerThreads.Length; ++i) 
    { 
     //theThreads[counter] = new Thread(new ThreadStart(MethodName)); 
     this.subWorkerThreads[i] = new Thread(() => searchItem(this.startRange, this.totalRangePerThread)); 
     //this.subWorkerThreads[i].Start(); 
     this.startRange = this.startRange + this.totalRangePerThread; 
    } 

    for (int threadIndex = 0; threadIndex < this.subWorkerThreads.Length; ++threadIndex) 
     this.subWorkerThreads[threadIndex].Start(); 
} 

searchItem 방법 :

public void searchItem(int start, int pagesToSearchPerThread) 
{ 
    for (int count = 0; count < pagesToSearchPerThread; ++count) 
    { 
    //searching routine here 
    } 
} 

내가 .NET에서 대의원, 행동, 사건에 대해 알고 있지만 confusing..This을 받고있다 스레드로 작업을하고 내가 사용하고있는 코드입니다 스레드의 공유 변수 사이에 문제가 있습니다. 스레드 세이프 프로 시저로 만드는 방법을 안내해 줄 수 있습니까?

+0

제목을 편집했습니다. "[제목에"태그 "가 포함되어 있어야합니까?] (http://meta.stackexchange.com/questions/19190/)"합의가 "아니오, 그렇지 않아야합니다"로 표시되어야합니다. –

+0

@JohnSaunders는 다음 번에 조심할 것입니다. 감사합니다. – faizanjehangir

+0

@faizanjehangir - FTS 기능을 제공하는 데이터베이스를 사용 해본 적이 있습니까? 이것은 수동으로 수행하는 경우 DDOS에 실제로 영향을받습니다. – tjameson

답변

1

실제 문제는 Thread 생성자의 labmda 표현식이 외부 변수 (startRange)를 캡처하고 있다는 것입니다. 그것을 해결하는 한 가지 방법은 다음과 같이 변수의 사본 만드는 것입니다 : 스레드를 만들고 시작하는

for (int i = 0; i < this.subWorkerThreads.Length; ++i) 
{ 
    var copy = startRange; 
    this.subWorkerThreads[i] = new Thread(() => searchItem(copy, this.totalRangePerThread)); 
    this.startRange = this.startRange + this.totalRangePerThread; 
} 

자세한 정보를 참조하십시오 조 Albahari의 우수한 ebook (아래로 조금 더 캡처 변수에 대한 섹션도있다). 폐쇄에 대해 자세히 알아 보려면 this 질문을 참조하십시오.

+0

정보를 제공해 주셔서 감사합니다. 더 자세히 살펴 보겠습니다. – faizanjehangir

1

첫 번째 대답은이 스레드가 실제로 변수를 공유하는 데 많은 작업을 필요로하지 않는다는 것입니다 (내가 올바르게 이해한다고 가정). 그들은 일부 공유 입력 변수 (예 : 대상 웹 서버)를 가지고 있지만 변경되지 않기 때문에 스레드로부터 안전합니다. 계획은 그들이 검색 한 레코드를 포함하는 데이터베이스 또는 일부를 구축한다는 것입니다. 5 개로 구성된 각각의 입력 아카이브를 채우고 하위 작업자 스레드가 모두 완료되면 단일 스레드로 병합하면됩니다. 어떻게 든 데이터를 저장하는 데 사용하는 아키텍처가 비용이 많이 든다면 ... 저장하려는 계획의 수와 저장할 계획이 적절하게된다면 무엇을 공유 할 수 있을까요? 사람들은?

+0

변수가 공유한다는 것은 변수'start'가 종료된다는 사실입니다 마지막 스레드에 의해 업데이트 된 값을 갖는다면, 이전 스레드를 덮어 씁니다 ... – faizanjehangir

+0

그래서 그것을 덮어 쓰지 마십시오. 각 스레드가 새 로컬 변수를 만들고 입력 매개 변수를 변경하지 마십시오. 필자는 개인적으로 입력 매개 변수를 기본적으로 혼자 좋은 코딩 연습으로 일반적으로 남겨 두는 것을 고려합니다. –

+0

하지만 시작될 때마다 생성 된 스레드가 동일한 함수'searchItem'을 공유하지 않을까요? 서로 다른 변수를 덮어 쓰거나 사용 하시겠습니까? – faizanjehangir

관련 문제