2017-11-02 5 views
0

나는 boost :: ref를 사용하여 스레드로 전달하는 포인터 (객체)의 벡터를 가지고 있으며이 스레드에서 객체의 일부 변수를 수정합니다. 메인 스레드로 돌아 왔을 때 스레드의 변경 사항이 적용되지 않고 기본값을 갖습니다. 나는 이것을 디버깅했으며 스레드에서 변경되었지만 메인 스레드에서는 변경되지 않았습니다. 그것은 boost :: ref가 작동하지 않고 매개 변수가 값에 의해 전달되는 것과 같습니다.별도의 스레드에서 수정 한 경우 내 변수가 변경되지 않는 이유는 무엇입니까?

누군가 내가 잘못하고있는 것을 보여줄 수 있습니까?

std::vector<Chunk *> chunks = divideScreen(width, height, chunkSize); 

for (Chunk * chunk : chunks) { 
    chunk->changed = 1; //initial value is 0, change it to 1 before passing to thread 
    boost::thread chunkThread = boost::thread(boost::bind(&Renderer::render, this, boost::ref(chunk))); 
} 

//wait for threads to finish 


//back in main thread 
std::cout << chunks[0]->changed << endl; //prints 1 


void Renderer::render(Chunk * chunk) { 
    chunk->changed = 2; //should be 2 - prints 2 in thread 
} 
+0

[mcve] – user463035818

+1

btw를 제공하십시오. 왜 포인터를 참조 할 필요가 있다고 생각하는지 이해할 수 없습니다. 두 개의 간접 참조가 하나이면 충분합니다. – user463035818

+0

"스레드가 완료 될 때까지 대기" . 당신은 항상 당신의 스레드에서'chunkThread.join()'또는'chunkThread.detach()'를 호출해야합니다. 내 추측이 정확하지 않은 경우 완전한 예를 제공해주십시오. – Ptaq666

답변

2

당신은 for 루프를 종료 한 후 '존재'스레드를 더 이상 수행하지 않는 chunk 변수에 대한 참조를 제공합니다.

스레드가 일부 값을 변경하는 것을 볼 수 있지만 실제로는 일부 부실한 chunk 변수를 역 참조하고 (예측할 수없는) 내용을 포인터로 사용하여 changed 멤버라고 생각되는 메모리 위치를 변경합니다.

너는 ref을주지 말아야한다. 스레드는 포인터를 가지고있는 변수 이 아니라 실제 포인터를 필요로합니다.

+0

그게 다야, 고마워! – user

+0

젠장, 난 잘했다. 작업을 다른 스레드에 위임 할 때 참조를 피하십시오 (람다 캡처와 동일). – xtofl