5

pthread_create()と関数を使用してマルチスレッドプログラムを作成していますが、本来のスレッドが実際には終了していないpthread_cancel()ことに気付きました。pthread_cancel()

void check(void *param){
    header_t *Bag = (header_t *) param;
    pthread_t timer_thread;
    while(true){
        if(Bag->size && TIMER_OFF){
            pthread_create(&timer_thread, NULL, (void *) &timer, (void *) Bag);
            printf("\nCREATE THREAD ID = %d\n", timer_thread);
            // ADD
        }
        else if(!TIMER_OFF && Bag->size >= 2 && Bag->next->time <= CURRENT_APT_TIME && CRRENT_TAG != Bag->next->tag){
            printf("\nOLD THREAD ID = %d TO BE CANCELLED\n", timer_thread);
            pthread_cancel(timer_thread);
            pthread_create(&timer_thread, NULL, (void *) &timer, (void *) Bag);
            printf("\nNEW THREAD ID = %d\n", timer_thread);
            // Replace
        }
        Sleep(1);
    }
}

タイマー関数void timer(void *)はまさにそのように聞こえます、そして私はそれ自体のスレッドIDを出力するために数行を含めました。

テストしたところ、次のことがわかりました。

...

OLD THREAD ID = 6041240 TO BE CANCELLED

NEW THREAD ID = 6046456

...

THREAD ID EXECUTING = 6041240

pthread_cancel()したがって、タイマー関数は?を呼び出すことによって終了しませんでした。

4

2 に答える 2

9

デフォルトでは、スレッドはキャンセルタイプ PTHREAD_CANCEL_DEFERREDで作成されます。つまり、スレッドにいわゆるキャンセルポイントがあることを確認する必要があります。つまり、キャンセル要求がチェックされ、対応されるポイントです。

このページには、キャンセルポイントとなることが保証されている機能のリストが含まれています。例として、sleep()およびpthread関数の一部があります。pthread_testcancel()スレッドがキャンセルされたかどうかを純粋にテストする関数だけが必要な場合にも使用できます。他には何もありません。

もう1つのオプションはPTHREAD_CANCEL_ASYNCHRONOUS、を使用してスレッドのキャンセルタイプをに設定することです。これによりpthread_setcanceltype()、キャンセルポイントがなくてもスレッドをキャンセルできます。ただし、システムはスレッドを実際にキャンセルするタイミングを自由に選択できます。キャンセル時にシステムが一貫性のない状態のままにならないように細心の注意を払う必要があります(通常、システムコールを回避し、同様-非同期キャンセルセーフ関数のリストを参照してください-短いです!)。

一般に、非同期キャンセルは、多かれ少なかれ「純粋な」処理スレッドにのみ使用する必要がありますが、システムコールなどを実行するスレッドは、キャンセルを延期し、キャンセルポイントを慎重に配置することでより適切に実装されます。

また、スレッドをデタッチしない限り(属性を介してデタッチを作成するか、作成後に呼び出すことによって)、キャンセル後にすべてのリソースがクリーンアップされることを確認するためにタイマースレッドをpthread_detach()呼び出す必要があります。pthread_join()それ。そうしないと、予備のスレッドリソースがない状態になり、新しいスレッドを作成できない可能性があります。

于 2012-06-30T08:00:53.373 に答える
0

のデフォルトのキャンセル方法pthread_cancel()は遅延キャンセルです。したがって、を呼び出すpthread_cancel()と、指定したスレッドがキャンセルポイントに到達する前に実際にキャンセルされることはありませんpthread_setcanceltype。スレッドに別のキャンセル方法を設定するには、を呼び出す必要があります。

于 2012-06-30T07:46:42.337 に答える