2012-04-09 10 views
0

하나의 루프에서 취소하려는 약 6 개의 스레드 ID 배열이 있습니다. 이것은 이러한 스레드가 정리 후에 잘못된 메모리에 액세스하려고 시도하여 특정 seg 오류가 발생했기 때문입니다. 취소 유형을 asynchronous으로 변경하면 스레드 취소 후에도 분할 오류가 계속 발생합니다. 취소 유형을 deferred으로 변경하고 취소 지점을 pthread_join으로 유지하면 2 회의 스레드 취소 후 코드가 결합에 의해 차단되고 종료되지 않습니다.루프에서 pthreads 취소하기

문제의 원인을 제시해주세요.

/* The cancel type is deferred and cancellation point is pthread_join. After 2  
iterations, it is unable to come out of join and gets blocked. Here is the code:*/ 

for (int i=0;i<N_BATCH_THREADS;i++) 
{ 
    rc = pthread_cancel(g_batch_th[i]); 
    if(rc!=0) 
    { 
     fprintf(stderr,"Error in pthread cancel\n"); 
     exit(1); 
    } 
    else 
    { 
     fprintf(stderr,"Thread cancelled successfully %d\n",g_batch_th[i]); 
    } 
    rc = pthread_join(g_batch_th[i],&status); 
    if(rc!=0) 
    { 
     fprintf(stderr,"Error in pthread join\n"); 
     exit(1); 
    } 
    else 
    { 
     fprintf(stderr,"Return from pthread join successful %d\n",g_batch_th[i]); 
    } 
    if(status != PTHREAD_CANCELED) 
    { 
     fprintf(stderr,"Unexpected thread status \n"); 
     exit(1); 
    } 
} 
+0

해당 코드 조각을 추가 할 수 있습니까? –

답변

0

지연 취소를 오해 한 것 같습니다. 코드 예제에서 다른 스레드의 취소를 "호출"하지 않는 pthread_join을 호출하는 다른 스레드의 취소를 수행하는 스레드입니다. 오히려 취소 된 스레드가 취소 지점을 호출 할 때 실제로 종료됩니다.

반면 비동기 취소를 사용하면 스레드 종료가 더 많거나 적게 발생하지만 실제로는 더 많거나 적습니다. 스레드 종료는 pthread_cancel이 반환되기 전에 발생한다고 보장 할 수 없으므로 취소 된 스레드는 매우 짧은 시간 동안 계속 실행될 수 있으며 제대로 종료되기 전에 segfault 할 시간이있을 수 있습니다. 또한 스레드 취소 콜백을 등록한 경우도있을 수 있습니다.이 콜백은 또한 segfault 일 수 있습니다. 물론 세부 사항을 모른 채 구체적인 내용을 말할 수는 없습니다.

+0

네,하지만 제 문제가 해결되었습니다. 문제는 스레드가 cond 변수를 기다리고 있다는 것이 었습니다. pthread_cond_wait는 취소 지점이기도하므로 스레드에게 신호를 보내고 요청을받은 후에 취소합니다. 따라서 스레드는 뮤텍스 잠금을 유지하면서 사망합니다. 다른 쓰레드의 취소 요청이 pthread_cond_wait에 가면, 그 쓰레드는 뮤텍스를 기다리고 (죽은 프로세스가 보유하고있는) 잠금을 해제하고 그 자체를 영원히 차단합니다. 이에 대한 해결책으로 취소 및 결합 대신 내 자신의 정리 프로세스를 구현했습니다. –