将堆栈变量传递给pthread_cleanup_push
我有一个使用文件描述符的线程,并且必须在取消时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); .... }
我有一个选择是将fd
从thread
传递给void *
,并让thread_cleanup
将其thread_cleanup
转换为int
,但如果sizeof(int) != sizeof(void *)
,这可能会导致问题。 我的问题是:当以这种方式使用时,正如在伪代码安全中那样传递堆栈变量吗?
你对sizeof
关注似乎是基于一些混乱。 int
和void *
之间没有转换,因此无论它们是相同的大小,还是一个的值都能在另一个中表示,都是无关紧要的。 发生的事情是fd
的地址,即int *
类型的指针值,正被转换为void *
并返回到int *
。 这是void *
的全部要点,是完全正确的用法。
至于指向对象是否“在堆栈上”(在推送/弹出清除处理程序的函数中具有自动存储持续时间的对象)是否重要,答案是肯定的,但您的使用是可以的。
forms上(正如POSIX中的当前规范所写),任何其生存期未在取消之前结束的对象仍然存在,并且可以从所有清理处理程序访问。 但是,这似乎是标准中的一个错误,因为它与支持基于展开的实现(如大多数实际实现)的Rationale文档冲突,其中取消清理处理程序在它们被推送的块上下文中执行。 由于对象int fd;
在函数thread
中,生命周期与pthread_cleanup_push
块之外的包含块相关联,从清理处理程序thread_cleanup
访问它是完全安全的。