2016-05-07 11 views
0

私のプログラムでは、pthreadは生成され、条件を待っています。待機中にキャンセルされることがあります。これはしばらくの間動作しますが、動作を停止します。スレッドはミューテックスをもう取得できません。条件を何度も待っている間にpthreadをキャンセルできないのはなぜですか?

以下はSSCCEです。 routineコードは、pthread_cond_waitのよく知られている標準的な例に従っていますが、状態が決して通知されないので、私はwhile (の条件が真でないことを除いて、)を待っています(チェックしても同じ問題が表示されます)。

わかりやすくするために、私はシステムコールの返品確認はしていませんが、すべて成功しています。

#include <stdio.h> 
#include <semaphore.h> 
#include <pthread.h> 
#include <unistd.h> 

pthread_mutex_t global_lock; 
pthread_cond_t global_cond; 

void *routine(void *arg) { 
    pthread_mutex_lock(&global_lock); 
    printf("waiting...\n"); 

    /*the condition will never arrive*/ 
    pthread_cond_wait(&global_cond, &global_lock); 
    pthread_mutex_unlock(&global_lock); 
    return NULL; 
} 

int main() { 
    pthread_t thread; 

    pthread_cond_init(&global_cond, NULL); 
    pthread_mutex_init(&global_lock, NULL); 

    while (1) { 
     pthread_create(&thread, NULL, routine, NULL); 

     /* 
     ** give thread enough time to start waiting 
     ** should perhaps have thread signal us it started waiting 
     ** but this is good enough for this example 
     */ 
     sleep(1); 

     pthread_cancel(thread); 
    } 

    return 0; 
} 

これは、毎秒waiting...と表示されると思います。しかし、それは2回印刷されます.3回目です。routineは最初にミューテックスを取得できません。なぜ??

+1

スレッドはキャンセルされません。 'ps -eLf'を実行すると、より多くのスレッドが開始され、終了しないスレッドが増えていることがわかります。私の推測では、 'pthread_cond_wait'は、関数が入力されたときに一度だけ取り消し点のように動作します。取り消しタイプを 'PTHREAD_CANCEL_ASYNCHRONOUS'に設定することで問題は解決されますが、リソースが漏れてしまう可能性があります。 – gudok

+0

@gudok私はリターンのチェックはしませんでしたが、すべて成功したので、 'pthread_cancel'は成功します。 –

+1

'pthread_cancel'のゼロ終了ステータスは、キャンセル要求がキューに入れられたことを意味します。特に、ターゲットスレッドが終了するまで待機しません。 – gudok

答えて

0

私は何か考えた後、EOFのコメントを使用して問題を解決できました。 EOFが自分で回答を投稿したい場合や、自分の回答の一部または全部をコピー&ペーストしたい場合は、その回答を受け入れます。

私のコードの問題は、キャンセルポイントの "クリーンアップハンドラ"をpthread_cond_waitに設定しないことです。 routineの修正されたコードは次のとおりです。これで、期待どおりに動作します。

void cleanup_handler(void *plock) { 
    pthread_mutex_unlock(plock); 
} 

void *routine(void *arg) { 
    pthread_cleanup_push(cleanup_handler, &global_lock); 

    pthread_mutex_lock(&global_lock); 
    printf("waiting...\n"); 

    /*the condition will never arrive*/ 
    pthread_cond_wait(&global_cond, &global_lock); 
    pthread_mutex_unlock(&global_lock); 

    pthread_cleanup_pop(0); 
    return NULL; 
} 
関連する問題