2011-10-31 9 views
0

스레드를 사용하여 모든 작업을 빠르게 처리 할 수있는 프로젝트가 있습니다. 우리는 개별 스레드에서이 함수를 호출 할 수 있도록하려면 : 스레드를 생성 할 때 boost :: thread 런타임 오류가 발생했습니다.

Request& Filter::processRequest(Request& req) 

그러므로 나는 반환 값에 액세스 할 수 있도록 람다 식의 기능을 포장.

는 이제 다음과 같은 런타임 오류가 발생합니다 :

glibc detected ... double free or corruption (!prev): ... 

나는 모든 것이 잘 작동 그룹에 스레드를 추가하려면 행의 주석을 해제합니다.

boost::thread_group thread; 
for (std::set<boost::shared_ptr<Filter> >::iterator i = sources_.begin(); 
    i != sources_.end(); ++i) { 
     Request ret 
     thread.add_thread(new boost::thread(boost::lambda::var(ret) = 
      (*i)->processRequest(req))); 
     req+=ret; 
     ... 
} 
thread.join_all(); 

이 런타임 오류의 원인은 무엇 일 수 있습니다. 아니면 개별 스레드에이 함수를 넣는 다른 방법이 있습니까?

+0

부스트 :: lambda :: var (ret) = (* i) -> processRequest (req)'할일? 당신은 N 개의 스레드를 추가하는 루프에 있습니다 ... 그래서 N 개의 안정적인 "ret"장소에서 결과를 참조로 저장합니까? – HostileFork

+0

ret와 함께하고 싶은 코드 위에 코드를 추가했습니다. 나는 그것을 req에 추가하고 싶다. 나는 ret의 사본이 모든 스레드에 넣어 지거나이 가정이 잘못되었다고 생각 했는가? – tune2fs

+1

저는'boost :: lambda' 사용자가 아니기 때문에'boost :: thread'로 약간의 수정 만 했으므로 실제로 접근 방법에 대해 많이 알지 못합니다. 할 수있다 "). 비동기 작업을 시작하면 계산이 끝났음을 보증하지 않고 결과를 사용할 수 없습니다. 그리고 문서는'boost :: lambda :: var'가 참조에 의한 인수를 취할 것을 제안합니다 ("복사"한다면 어떻게 호출자가 사본에 연결하겠습니까?) ... 그래서 당신은 정말로 하나의'Request ret; '루프의 반복마다 "살아있다". – HostileFork

답변

1

이런 종류의 기술이 전혀 작동하지 않는다면 안정적으로 참조 할 수있는 여러 개의 ret 값 (각 실행 스레드마다 하나씩)이 필요합니다. 그리고 당신은 당신이 그 값을 사용할 때까지 당신의 스레드 조인이 완료 될 때까지 기다려야 할 것입니다.

간단한 수정을하면 vector<Request> retValues ... 루프 외부의 벡터를 만든 다음 add_thread 때마다 요소를 벡터에 추가하고 해당 요소에 대한 참조를 전달할 수 있습니다. 그런 다음 값을 사용하기 위해 조인이 끝날 때까지 기다리면 아마도 작동할까요?

boost::thread_group thread; 
vector<Request> retValues; 
for (std::set<boost::shared_ptr<Filter> >::iterator i = sources_.begin(); 
    i != sources_.end(); ++i) { 
     retValues.push_back(0); 
     thread.add_thread(new boost::thread(
      boost::lambda::var(retValues.back()) = 
      (*i)->processRequest(req))); 
     ... 
} 
thread.join_all(); 
// retValues safe to use here... 

(참고 : boost::lambda를 사용하는 것은 아마 필요가 없습니다, 당신은 결과를 저장하는 노동자 클래스에 연결하는 부스트 : : 바인딩을 사용할 수 있습니다 : 정말

Getting return value from a boost::threaded member function?

을 ...하지만, 결과를 저장하기 위해 스레드마다 별도의 변수가 필요합니다 ... 스레드의 수명이 스레드에서 쓸 수있을만큼 오래 지속됩니다.)

+0

'boost :: thread'에서 파생 된 것은 가상 소멸자가 없기 때문에 좋은 생각이라고 생각하지 않습니다. 아니면 내가 잘못 했니? – tune2fs

+0

흠, 네 말이 맞아 보이는 군. 기묘한. QThread와는 꽤 다른 것 같아요 ... 다시 보죠 ... http://doc.qt.nokia.com/latest/qthread.html#details – HostileFork

+0

답장을 보내 주셔서 감사합니다. 나는 그것을 시도 할 것이다. 또한 QThreads를 살펴볼 것입니다. – tune2fs

관련 문제