将堆栈变量传递给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); .... } 

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

你对sizeof关注似乎是基于一些混乱。 intvoid *之间没有转换,因此无论它们是相同的大小,还是一个的值都能在另一个中表示,都是无关紧要的。 发生的事情是fd的地址,即int *类型的指针值,正被转换为void *并返回到int * 。 这是void *的全部要点,是完全正确的用法。

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

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