【问题标题】:pthread clean up handlerpthread 清理处理程序
【发布时间】:2018-02-01 09:48:46
【问题描述】:

我有一些动态分配,我想确保在线程退出/终止时释放它们。

请考虑以下场景:

static void thread_cleanup_handler(void* arg)
{
    free(arg);
}

static void* threadFunction(void* arg)
{
    pthread_cleanup_push(thread_cleanup_handler, arg);
    //do some work with arg...
    pthread_cleanup_pop(1);
    return NULL;
}

something* data = (something*)malloc(sizeof(something));
pthread_create(&id, &attr, threadFunction, (void*)data); //thread is created detached

问题是,如果创建的线程在它实际开始运行之前被取消(使用pthread_cancel)(它只是被调度并且尚未被执行),清理处理程序会被调用还是被调用?这是潜在的内存泄漏?

请注意线程是用 PTHREAD_CREATE_DETACHED 创建的。

【问题讨论】:

    标签: c linux multithreading pthreads


    【解决方案1】:

    来自the POSIX reference for pthread_cancel

    当取消操作时,线程的取消清理处理程序将被调用。

    因此,如果线程被取消,任何已安装的清理处理程序都会运行。您的代码的问题是,如果线程函数尚未调用 pthread_cleanup_push,则没有可运行的清理处理程序。正如您所怀疑的那样,导致泄漏。

    【讨论】:

    • 这就是我所害怕的,有什么可能的解决方案/建议吗?
    • @Tsef 我认为您实际上不必担心。调用pthread_cancel 实际上并不会立即取消线程。相反,线程必须达到一个取消点,在你的例子中,我认为在“调用”pthread_cleanup_push 之前没有取消点。因此,您永远不会有泄漏,因为清理处理程序将在第一个可能的取消点之前注册。
    • 如果有人需要,请在此处提供更多相关信息(线程必须运行才能取消):stackoverflow.com/questions/17719933/…
    【解决方案2】:

    默认情况下没有泄漏。

    POSIX.1 指定某些函数必须,而某些其他函数必须 功能可能是取消点。如果线程是可取消的......那么线程在调用函数时被取消 那是取消点。

    ——pthreads(7), Linux

    因此,您的线程将一直运行,直到它调用已定义为“取消点”的系统调用——通常这些是阻塞系统调用。请参阅a list of cancellation points 此处;真正的列表取决于操作系统。

    这假定您的线程的cancelability type 设置为PTHREAD_CANCEL_DEFERRED,这是默认状态。如果将 cancability 类型设置为 PTHREAD_CANCEL_ASYNCHRONOUS,则存在泄漏风险。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2013-03-02
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2017-06-24
      • 2012-04-18
      • 1970-01-01
      相关资源
      最近更新 更多