1

pthreads に関する試験の準備と、pthreads を適切にキャンセルするためのコードが提供されています。何が間違っているのかを説明し、修正するよう求められました。

私の答え: スレッド ハンドラー関数はミューテックスを解放せずに待機状態になりますが、何かが足りない気がします。コードは次のとおりです。プログラムを修正するために、クリーンアップ ハンドラを追加する行が追加されました。繰り返しますが、なぜこれが機能するのかよくわかりません。(クリーンアップハンドラーの概念は理解していますが、なぜこの特定の問題を修正するのか理解できません - 私の答えが正しいかどうかわからないもう1つの理由)

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

pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER;
pthread_cond_t cv = PTHREAD_COND_INITIALIZER;
const int flag = 1;

static void * cancelme(void *bb_in)
{
  pthread_mutex_lock(&mutex);

  /* Install a cleanup handler */
  pthread_cleanup_push(pthread_mutex_unlock, &mutex);

  while (flag) {
    pthread_cond_wait(&cv, &mutex);
  }

  //before insertion of cleanup handlers: pthread_mutex_unlock(&mutex); was here

  /* Uninstall cleanup handler */
  pthread_cleanup_pop(1);



  return (NULL);
}

int main()
{
  pthread_t t;
  pthread_create(&t, NULL, cancelme, NULL);
  sleep(1);
  pthread_cancel(t);

  printf("Waiting for thread to finish...\n");
  pthread_join(t, NULL);
  printf("Thread finished...\n");

  printf("Waiting to acquire lock...\n");
  pthread_mutex_lock(&mutex);
  printf("Lock acquired\n");

  return (0);
}

どんなフィードバックでも大歓迎です。

4

1 に答える 1

2

pthread_mutex_unlockスレッドのクリーンアップ スタックに関数をプッシュするpthread_cleanup_pushコードは、コード スニペットを機能させるように見えます。

関数をクリーンアップ スタックにプッシュすることで、スレッドは、終了が強制されて関数がヒットしなくpthread_mutex_unlockても、スレッドの終了時にミューテックスがロック解除されるようにします。pthread_cleanup_pop

本質的に、クリーンアップ キューを使用すると、終了時にコードが実行される/リソースが解放される/などを確実に行うことができます。はクリーンアップ スタックの最pthread_cleanup_pop function上位の関数を呼び出すだけで、終了はクリーンアップ スタックのすべての関数を呼び出します。詳細については、man ofpthread_cleaup_pushを参照してください。

于 2012-08-13T17:50:25.710 に答える