将堆栈变量传递给pthread_cleanup_push

时间:2014-08-23 22:29:16

标签: c pthreads

我有一个使用文件描述符的线程,取消时必须close()文件描述符。伪代码看起来像:

static void thread_cleanup(void *args)
{
    int *fd = (int *)args;
    close(*fd);
}

void *thread(void *arg)
{
    int fd = open(...);
    ...
    pthread_cleanup_push(thread_cleanup, &fd);
    ....
}

我选择的一个选项是将fdvoid *投放到thread,然后让thread_cleanup将其投放回int,但这样做如果sizeof(int) != sizeof(void *)可能会导致问题。我的问题是:以这种方式使用时,是否像伪代码安全一样传递堆栈变量?

1 个答案:

答案 0 :(得分:1)

您对sizeof的担忧似乎是基于一些混乱。 intvoid *之间没有转换,因此无论它们是相同的大小,还是一个的值都可以在另一个中表示,都是无关紧要的。发生的事情是,fd的地址(类型为int *的指针值)正在转换为void *并返回int *。这是void *的重点,非常正确。

至于指向对象是否“在堆栈上”(在推送/弹出清除处理程序的函数中具有自动存储持续时间的对象)是否重要,答案是肯定的,但您的使用是可以的

形式上(正如POSIX中的当前规范所写),任何其生存期未在取消之前结束的对象仍然存在,并且可以从所有清理处理程序访问。但是,这似乎是标准中的错误,因为它与支持基于展开的实现(如大多数实际实现)的Rationale文档冲突,其中取消清理处理程序在它们被推送的块上下文中执行。由于函数int fd;中的对象thread具有与pthread_cleanup_push块之外的包含块关联的生命周期,因此从清理处理程序thread_cleanup访问它是完全安全的。