2

pthread_cancel() は、Solaris 10、Linux、および Cygwin で sleep() を正常に中断します。では、なぜ sleep() の代わりに pthread_cond_timedwait() を使うのでしょうか?
次の例の PPBsleep() は、あるライブラリで見つけた関数です。システムクロックの調整に対して脆弱だと思います。

PPBsleep2() 私は自分で書きました。PPBsleep() より悪くないと思います。また、単純な sleep() も機能します。

#include <time.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/time.h>
#include <pthread.h>
#include <errno.h>
#include <stdio.h>

int PPBsleep(int seconds)
{
  int  rc;
  struct timeval now;
  struct timespec timeout;
  pthread_cond_t sleep_cond = PTHREAD_COND_INITIALIZER;
  pthread_mutex_t sleep_mutex = PTHREAD_MUTEX_INITIALIZER;

  rc = pthread_mutex_lock(&sleep_mutex);

  rc = gettimeofday(&now,NULL);

  timeout.tv_sec = now.tv_sec + (long)seconds;
  timeout.tv_nsec = now.tv_usec * 1000L;
  rc = 0;
  while(rc != ETIMEDOUT) {
    rc = pthread_cond_timedwait(&sleep_cond, &sleep_mutex, &timeout);
  }

  rc = pthread_mutex_unlock(&sleep_mutex);

  return 0;
}

int PPBsleep2(int seconds)
{
  int oldtype;
  pthread_setcanceltype(PTHREAD_CANCEL_ASYNCHRONOUS, &oldtype);
  sleep(seconds);
  pthread_setcanceltype(oldtype, NULL);
  return 0;
}

void *ThreadStartFunction(void *inp)
{
  pthread_setcanceltype(PTHREAD_CANCEL_DEFERRED, NULL);
  //pthread_setcanceltype(PTHREAD_CANCEL_ASYNCHRONOUS, NULL);
  printf("before sleep\n");
  fflush(stdout);
  //PPBsleep2(4);
  sleep(4);
  printf("after sleep\n");
  fflush(stdout);
  return NULL;
}

int main() {
  int rc;
  void *res;
  pthread_t thread;
  rc = pthread_create(&thread, NULL, ThreadStartFunction, NULL);
  sleep(1);
  pthread_cancel(thread);
  pthread_join(thread, &res);
  return 0;
}
4

1 に答える 1

2

sleep()POSIX によるキャンセル ポイントである必要があります (キャンセル ポイントのリストについては、このリンクを参照してください)。

したがって、POSIX 準拠のシステムではキャンセル ポイントとして機能する必要があります。

于 2013-06-06T09:16:09.483 に答える