2011-02-03 6 views
1

boost::threadpool (boost, link의 공식 파트가 아님)을 사용하여 프로그램의 특정 부분을 병렬 처리하려고합니다. 그러나, 내 프로그램 실속 및 검사시, 두 개의 비활성 스레드 (내 스레드 풀에서 용의자가) 및 하나의 스레드를 100 % (내 주 실행 스레드 용의자)에서 실행되는 나를 보여줍니다 htop 보여줍니다. 여기 boost :: bind를 boost :: bind와 함께 사용하면 무한 루프에서 프로그램이 중단됩니다.

는 관련 코드 :

namespace rt { 

class Renderer 
{ 
    public: 
    Renderer(int threads) : tp(threads) {} 

    void render(const Scene&, const Camera&, Image&) const; 

    private: 
    mutable boost::threadpool::pool tp; 
    //int tp; 

    static void render(const Scene&, const Camera&, Image&, int, int); 
    static Color trace_ray(const Ray&, const Scene&, int depth = 0); 
}; 

} // namespace rt
void 
Renderer::render(const Scene& scene, const Camera& cam, Image& image) const 
{ 
    for (int y = 0; y < image.get_height(); ++y) 
     for (int x = 0; x < image.get_width(); ++x) 
      tp.schedule(boost::bind(&Renderer::render, scene, cam, image, x, y)); 

    tp.wait(); 
} 

void 
Renderer::render(const Scene& scene, const Camera& cam, Image& image, int x, int y) 
{ 
    Color c = trace_ray(cam.spawn_ray(x + .25f, y + .25f), scene) 
      + trace_ray(cam.spawn_ray(x + .75f, y + .25f), scene) 
      + trace_ray(cam.spawn_ray(x + .25f, y + .75f), scene) 
      + trace_ray(cam.spawn_ray(x + .75f, y + .75f), scene); 

    image.set_pixel(x, y, c/4.0f); 
}

나는 문제가 내 boost::bind 구조로 거짓말을 의심하는 이유는 내가 void foobar() {} 기능을 만들고 boost::threadpool::pool::schedule에이를 통과 할 때, 프로그램은하지 않는다는 것입니다 그것에 무한 루프가 있습니다. 여기서 내가 뭘 잘못하고 있니?

+0

문제는 코드가 아닌 부스트 바인딩 또는 스레드 풀과 관련이 있다고 생각합니까? 라이브 잠금을 초래하는 동기화 문제가있는 것 같습니다. –

+0

이것은 가능할 수도 있습니다. 단지'boost :: threadpool' 대신에'asio :: io_service'를 사용하도록 코드를 다시 작성 했으므로 같은 오류가 계속 발생합니다. 그러나 나는 그것이 잠길지도 모른다는 단서가 없다. 더 낮은'render' 함수에서 볼 수 있듯이, 모든 함수는 몇몇 독립적 인 광선을 추적하고 이미지 (기본적으로 큰 배열)에 값을 설정합니다. 각 스레드는 배열의 다른 요소에만 액세스하고 쓰기 만하므로 라이브 잠금을 초래할 수있는 방법을 알지 못합니다. 그래서 나는 아마도'boost :: bind'를 잘못 사용하고 있다고 생각합니다. – robrene

+0

또한, 또 하나 : 스레드 풀에 하나의 스레드 만있을 때도 여전히 중단됩니다.그래서 이것은 동시성 문제처럼 보이지 않습니다. – robrene

답변

1

주어진 인수는 boost::bindwill be copied입니다. 복사하여 내부적으로 에 의해 개최한다 결합

인수는 함수 객체를 반환했습니다. 예를 들어 다음 코드에서 을 입력하십시오.

int i = 5;

bind (f, i, _1); i 값의 사본이 함수 오브젝트에 저장됩니다. boost :: ref 및 boost :: cref는 복사본이 아닌 함수 개체 저장을 개체에 저장하는 데 사용할 수 있습니다. 귀하의 경우에는

:

tp.schedule(boost::bind(&Renderer::render, scene, cam, image, x, y)); 

cam, image, xy-Rendered::render의 사본을 보내드립니다. 그게 네가 원하는거야?

+0

우수한 점이 있다면, boost :: ref는 적어도 장면과 아마도 카메라와 이미지에 대해서도 사용해야합니다. – AJG85

+0

이것은 그 것이었다! 복사 대신 실제 이미지 객체에 픽셀을 설정하고 최적화를 위해 장면과 카메라에 대한 참조를 설정하도록 이미지에 대한 참조를 보냅니다. 기본 복사 생성자가 어떻게 든 객체 중 하나에 대해 무한 루프를 입력했거나 다른 방식으로 실패하고 있었다고 생각합니다. – robrene

+0

@robrene 기꺼이 도와주세요. 행운을 빈다. –

1

대신에 boost :: thread_group을 즉석 스레드 풀로 사용 하시겠습니까? 여기서 wait()의 구현은 이름이 스레드가 무한정 비활성 상태가되는 이유가 될 수있는 장벽을 의미합니다.

편집 :

당신이 무한 루프에 가지 않고 렌더링 호출 할 수 있습니까? 아마도 그것은 당신이 보이지 않는 광선을 추적하거나 산란하는 방식 일 것입니다. 또한 스레드 풀에 wait_for_all_tasks으로 전화를 걸려면 구현에 게시 한 링크를 잠시 훑어 보면됩니다.

+0

어떤 종류의 멀티 스레딩도 사용하지 않고 메인 실행 스레드에서 모든 것을 실행하면 원래 포스트에 추가해야합니다. 정상적으로 작동하고 예쁜 그림을 얻습니다. 문제는 내 렌더링 알고리즘에 있지 않습니다. 멀티 스레딩은 기본 작업이 작동한다는 것을 알기 위해 제가 지금 맞추려고하는 것입니다. – robrene

+0

함수의 구현에 따라 장면과 같은 공유 객체에 대한 모든 스레드 액세스에 중요한 섹션을 추가해야 할 수도 있습니다. – AJG85

관련 문제