2012-07-03 2 views
0

다음 (의사) 코드는 이해하지 못하는 일부 동작을 유발합니다. 병렬로 실행되는 2 개의 스레드가 있습니다. 둘 다 똑같은 (복잡한) 계산을하지만, 어느 것이 먼저 완료 될지는 모른다. 반복적으로 실행하면 첫 번째가 더 빠르며 두 번째가 빠를 경우가 있습니다. 이것은 정상이며 정상적으로 작동합니다. 그런 다음 첫 번째 성공한 스레드는 다른 스레드를 종료해야하며 둘 다 함께 포크해야합니다. 그러나 첫 번째 솔버가 끝나면 모든 것이 작동하지만 두 번째가 먼저 끝나면 "조인 명령"은 첫 번째 솔버가 종료되었음을 인식하지 못합니다 (조인은 영원히 기다리고 프로그래머는 계속되지 않습니다). 내가 잘못했거나 다른 것을 할 수있는 아이디어가 있습니까?C++의 Pthread 취소

void* thread_function(...) 
{ 
    do_some_complex_task(); 
    if (successfull && first_finsihed) 
    { 
     pthread_chancel(other_thread); 
    } 
} 

int main() 
{ 
    std::vector<pthread_t*> store; 
    store.resize(2); 

    pthread_setcancelstate(PTHREAD_CANCEL_ENABLE, NULL); 
    pthread_setcanceltype(PTHREAD_CANCEL_ASYNCHRONOUS, NULL); 

    pthread_create(store[0], NULL, thread_function, ...); 
    pthread_create(store[1], NULL, thread_function, ...); 

    pthread_join(*store[0], NULL); 
    pthread_join(*store[1], NULL); 
} 

ps. 의사 코드가 상세하지 않으면 알려주십시오.

답변

1

의사 코드를 기반으로 한 스레드는 비동기 취소 대신 지연 취소 (기본값)가있을 수 있습니다. 취소 된 스레드가 cancellation point에 도달하지 않으면 pthread_join이 차단됩니다. pthread_create를 호출 할 때, 새로 생성 된 스레드는 상속 호출 스레드 :

취소하려는 스레드 내에서 pthread_setcanceltype을 호출 해보십시오. 디버거를 프로그램에 연결하여 스레드의 현재 상태를 식별 할 수도 있습니다.

이상적으로 가능하다면 pthread_cancel을 피하십시오. pthread 호출이 문서화되어 있지만 사소한 세부 사항으로 인해 정확한 동작을 얻고 유지하기가 어려울 수 있습니다. 일반적으로 스레드가 종료되도록 설정되어 있음을 나타내는 플래그를 설정하는 것이 더 쉽고, 함수가 설정된 경우 함수에서 리턴되기 시작합니다. do_some_complex_task에서는 복잡한 작업을 작은 작업으로 나누고 작은 작업 사이의 취소를 확인하십시오.

1

사용하지 마십시오 pthread_cancel - 전역 상태를 사용하고 각 스레드의 "주 루프"내부에서 확인하십시오. 스레드의 기능 종료 직전에 "on"으로 설정하십시오.

+0

그러면 어떻게 다른 스레드를 종료 할 수 있습니까? "do_some_complex_stask()"오랜 시간이 걸리므로 가능한 한 빨리 마무리되지 않은 스레드를 중지하고 싶습니다. – Martin

+0

'do_some_complex_task()'가 메모리를 할당하면 다른 스레드에서 "pthread_cancel()"을 호출하면 해당 메모리가 손실됩니다. 어쨌든, 이것은 올바른 방법이 아닙니다. 필요에 따라'do_some_complex_task()'를 중단하는 방법을 찾아야 할 것이다. – elcuco