【问题标题】:Passing stack variables to pthread_cleanup_push将堆栈变量传递给 pthread_cleanup_push
【发布时间】:2014-10-17 11:35:41
【问题描述】:

我有一个使用文件描述符的线程,并且在取消时必须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);
    ....
}

我的一个选择是将fdthread 转换为void *,并让thread_cleanup 将其转换回int,但如果sizeof(int) != sizeof(void *) 可能会导致问题。我的问题是:以这种方式使用伪代码中的堆栈变量是否安全?

【问题讨论】:

    标签: c pthreads


    【解决方案1】:

    您对sizeof 的担忧似乎是基于一些困惑。 intvoid * 之间没有转换,因此它们是否相同大小,或者一个值是否可以在另一个中表示,是无关紧要的。正在发生的事情是fd 的地址,int * 类型的指针值,正在被转换为void * 并返回到int *。这就是void * 的全部意义,而且是完全正确的用法。

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

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

    【讨论】:

    • 感谢您的澄清!至于sizeof 问题,我最初的计划是致电pthread_cleanup_push(thread_cleanup, (void *)fd) 并让thread_cleanup 致电close((int)args)。我可能应该完全删除我帖子的那一部分,因为它并不真正相关。
    • 我明白了。是的,这种方法将取决于 int 在往返于 void * 和返回时的值。但是用你的方法没关系。
    猜你喜欢
    • 2015-12-21
    • 2021-12-30
    • 2021-12-04
    • 1970-01-01
    • 2015-02-21
    • 2020-06-22
    相关资源
    最近更新 更多