将堆栈变量传递给 pthread_cleanup_push [英] Passing stack variables to pthread_cleanup_push

查看:55
本文介绍了将堆栈变量传递给 pthread_cleanup_push的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个使用文件描述符的线程,并且在取消时必须close() 文件描述符.伪代码如下:

I have a thread that uses a file descriptor and must close() the file descriptor when cancelled. The pseudocode looks like:

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

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

One option I had was to pass fd casted to a void * from thread, and have thread_cleanup cast it back to an int, but this may cause problems if sizeof(int) != sizeof(void *). My question is: is passing stack variables as in the pseudocode safe when used in this fashion?

推荐答案

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

Your concern about sizeof seems to be based on some confusion. No conversion between int and void * is taking place, so whether they are the same size, or whether the values of one can be represented in the other, is irrelevant. What's happening is that the address of fd, a pointer value of type int *, is being converted to void * and back to int *. This is the whole point of void * and is perfectly correct usage.

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

As for whether it matters that the pointed-to object is "on the stack" (an object with automatic storage duration in the function where the cleanup handler is pushed/popped), the answer is yes, but your usage is okay.

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

Formally (as the current specification in POSIX is written), any object whose lifetime did not end before cancellation was acted upon still exists and can be accessed from all the cleanup handlers. However, this seems to be a mistake in the standard, as it conflicts with the Rationale document which supports unwinding-based implementations (like most real-world implementations) where cancellation cleanup handlers execute at the block context where they were pushed. Since the object int fd; in the function thread has lifetime associated with the containing block outside the pthread_cleanup_push block, it's perfectly safe to access it from the cleanup handler thread_cleanup.

这篇关于将堆栈变量传递给 pthread_cleanup_push的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆