2012-06-16 2 views
1

나는 각 요소에 하나의 값을 포함하는 단일 연결 목록을 가지고있다.리스트에서 pthreads가 터지면서리스트에 데이터를 채우는 것

struct listElement 
{ 
    char guid[20]; 
    struct listElement *next; 
    struct listElement *last; 
    int numElements; 
}; 

는 코드 요소에 대한 모든 pthread_cond_wait() 목록에 추가하려면입니다 풀에 (10 개)의 pthreads를 시작합니다.

내 주요() 파일에서 문자열, 한 번에 한 줄을 읽고

listPush(val)이 잠금을 획득 새로운 요소를 생성 listPush(val)를 호출하여 연결리스트를 채우기, (목록의 끝 추가하거나 경우에 머리를 생성한다 비어 있음) 잠금을 해제하면 pthread_cond_signal()이 호출되어 10 개의 스레드 중 하나가 수행 할 요소가 있음을 알 수 있습니다.

numElements> numThreads 인 경우 각 스레드가 팝하고 이동하기에 충분한 작업이 있어야하기 때문에 pthread_cond_broadcast()을 호출합니다.

각 스레드 listPop(rVal)이 값을 해제 (잠금, 제거, 수정, 잠금 해제) 한 다음 처리하고 pthread_cond_wait() 상태로 돌아갑니다.

내 파일에는 약 2 억 개가 있습니다. (1.2GB) 나는 링크드리스트의 크기를 크게 잡으려고하지 않기 때문에 링크드리스트의 크기를 "제한"하려고한다. listPush() 내부

, 내가 뮤텍스를 고정하기 전에, 나는 아이디어는 내가 내 목록 "을 기입"하면 스레드가 더 추가하기 전에 그것의 덩어리를 처리하기 위해, 난 기다릴 것입니다

if(head && head->numElements >= maxNumElements) 
{ 
    while(head && head->numElements >= maxNumElements) 
    { 
     sleep(1); 
    } 
} 

있습니다. 앱이 "펄싱 (pulsing)"을 시작하는 지점에 이르렀습니다. 기본적으로 1 초 기다리는 것을 볼 수 있습니다. 나는이 일이 결코 일어나지 않거나 아주 드물게 일어날 것을 기대합니다.

sleep()을 사용하는 것 외에도 내 목록의 크기를 제한하는 더 좋은 방법이 있습니까?

+0

* unlocks는 pthread_cond_signal()을 호출합니다. * - 시그널링은 일반적으로 잠금 해제 전에 critical 섹션 내에서 수행됩니다. – chrisaycock

+0

각 소비자 스레드는 팝업 이후에도 목록이 아직 비어 있지 않은 경우 다음 소비 자에게 신호해야합니다. – jxh

+0

@chrisaycock : 그게 자주 수행되는 방법일지도 모르지만 그럴 필요는 없습니다. 사실 뮤텍스에 대한 경합을 어느 정도 줄여줍니다. –

답변

0

이것은 producer-consumer problem과 비슷합니다. 해결 방법은 목록이 너무 큰 경우 listPush()이 조건 변수를 기다리는 것입니다. 그런 다음 소비자 스레드 중 하나가 목록 요소가 소비 된 후이 조건 변수를 신호로 보낼 수 있습니다.

완전히 다른 접근 방식은 통신 및 동기화를 모두 처리하기 위해 pipe()을 사용하는 것입니다. 이렇게하면 연결된 목록과 뮤텍스 모두가 필요하지 않게됩니다.

+0

맨 페이지를 읽은 후,'pipe()'는 내가 찾고있는 것으로 보인다. 그것에 대해 결코 알지 못했다. 감사. 나는 그것을 시도 할 것이다. – utdrmac

0

예, sleep을 사용하는 대신 뮤텍스와 비슷하지만 다른 방식으로 세마포어를 기다릴 수 있으며 새 요소가 목록에 추가 될 때 각성 될 수 있습니다. 이벤트 라이브러리를 찾거나 pthread를 사용하여 직접 수행 할 수 있습니다.

관련 문제