2012-05-09 16 views
1

私はマルチスレッドSYSTERMを開発するためにcygwinの+ Eclispseインディゴ+ CDTを8.0.2を使用する、コードは以下である:pthread_Joinは呼び出し後に戻ることができませんpthread_cancel?

pthread_mutex_t mutexCmd = PTHREAD_MUTEX_INITIALIZER; 
pthread_cond_t signalCmd = PTHREAD_COND_INITIALIZER; 

void * Func(void * arg) 
{ 
    int iStatus; 
    while (1) 
    { 
     int a = 1; 
     pthread_cleanup_push(pthread_mutex_unlock, &mutexCmd); 
     pthread_mutex_lock(&mutexCmd); 
     iStatus = pthread_cond_wait(&signalCmd, &mutexCmd); 
     if (iStatus) { 
       err_abort(iStatus, "signalCmd status error"); 
     } 
     if(arg->Cmd != navi_Go) //Just a command tag; 
     { 
      pthread_mutex_unlock(&(pNaviCtrl->mutexCmd)); 
      continue; 
     } 
     //do some work 
     //..... 
     pthread_mutex_unlock(&mutexCmd); 
     pthread_cleanup_pop(1); 
    } 
//pthread_detach(pthread_self()); 
return NULL; 
} 

int main() 
{ 
    int iStatus = 0; 
    pthread = tid; 
    iStatus = pthread_create(&tid;NULL, Func, NULL); 
    if(iStatus) 
    { 
    err_abort(iStatus, "Start pthread error"); 
    } 
    // do some work 
    ... 
    //Cancel thread 
    void * retval; 
    iStatus = pthread_cancel(tid) 
    iStatus = pthread_join(tid; &retval); 
    if(iStatus){ 
     err_abort(iStatus,"Stop thread error"); 
    } 
    return iStatus; 
} 

プログラムの実行は、それがISTATUS = pthread_joinを(TID1」で停止する場合、& RETVAL ); "もはや先に進むことができなかった、私はスレッドがデッドロックにふらつくかもしれないと思うが、理由を見つけることができません。私はpthread_cancel()を呼び出した後、スレッドが終了してpthread_join()に戻ります。 私のコードに何が間違っているのか教えてください。

+0

「pthread_cleanup_push」と「pthread_cleanup_pop」をすべて削除したときに見つかったのですが、すべてのことはOKですが、理由をkownするのは好きです – user1383457

答えて

1

whileループ内にcleanup_pushと_popを入れないでください。それらを複数回呼び出さないでください。あなたがそれらを見ると、{}でそれらの間にコードをラップするマクロです。彼らは、pthread_cancelを呼び出すときに使用されるlongjumpを設定します。

+0

これは重要な点です。 – user1383457

1

pthread_cleanup_pop(1)は、スタックからクリーンアップエントリをポップするだけでなく、実行するようにpthreadライブラリに指示します。だからコールも暗黙的に呼び出します。

pthread_mutex_unlock(&mutexCmd); 

すでにミューテックスをアンロックしたので、その呼び出しは(mutex型がPTHREAD_MUTEX_NORMALであると仮定して)未定義の動作をしています。私はその電話がただ帰ってこないとか何かを想像しています。あなたのコードは、クリーンアップを手渡し、他の問題を抱えている

注 - ループのためcontinueを実行する場合は、あなたは別のクリーンアップコンテキストを追加しますpthread_cleanup_push()二回目(またはそれ以上)を呼び出します。

その他の問題がある可能性があります(私はpthread_cancel()に詳しくはわかりません)。

関連する問題