使用C中的清理处理程序安全取消pthread

时间:2012-08-13 17:40:14

标签: c linux multithreading concurrency pthreads

我们已经获得了一些代码,以便在准备有关pthreads的考试并正确取消它们时进行考虑。我们被要求解释什么是错的,并修复它。

我的回答:线程处理函数在没有释放互斥锁的情况下进入等待状态,但我觉得我错过了什么。这是代码,添加了清理处理程序的行添加来修复程序。再说一遍,我不太清楚为什么会这样。 (我理解清理处理程序的概念,但我不明白为什么它解决了这个特殊问题 - 另一个原因我不确定我的答案是否正确)

#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);
}

任何反馈都非常感谢。

1 个答案:

答案 0 :(得分:2)

看起来通过pthread_mutex_unlockpthread_cleanup_push函数推送到线程清理堆栈的代码使代码片段工作,否则线程会抓取共享锁并被强制退出而不释放它。

通过将pthread_mutex_unlock函数推送到清理堆栈,线程确保在线程退出时互斥锁将被解锁,即使强制退出并且pthread_cleanup_pop函数未被命中。

本质上,清理队列使您能够确保在退出时执行代码/释放资源/等。 pthread_cleanup_pop function只调用清理栈上的top函数,退出时调用清理栈上的所有函数。有关详细信息,请参阅pthread_cleaup_push的人。