我有一些动态分配,我想确保在线程退出/终止时释放。
请考虑以下情况:
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创建的。
答案 0 :(得分:1)
来自the POSIX reference for pthread_cancel
:
当取消操作时,应调用线程的取消清除处理程序。
因此,如果线程被取消,将运行任何已安装的清理处理程序。代码的问题在于,如果线程函数尚未调用pthread_cleanup_push
,那么就没有运行清理处理程序。正如您所怀疑的那样,导致泄密。
答案 1 :(得分:0)
默认情况下,没有泄漏。
POSIX.1指定某些功能必须,而某些其他 功能可能是取消点。如果线程是可取消的...则在调用函数时该线程被取消 那是一个取消点。
因此,您的线程将一直运行,直到它调用已定义为“取消点”的syscall为止-通常,这些阻塞了syscall。请参阅此处的a list of cancellation points;真正的列表取决于操作系统。
这假定您线程的cancelability type设置为PTHREAD_CANCEL_DEFERRED
,这是默认状态。如果将cancability类型设置为PTHREAD_CANCEL_ASYNCHRONOUS
,则有泄漏的风险。