关于pthread_exit释放自动变量的混淆
Confusion regarding pthread_exit freeing of automatic variables
根据此
"如果一个线程调用pthread_exit
, c++不保证析构函数是调用线程堆栈上的所有自动变量。一个很聪明的恢复方法功能是在线程函数的顶层调用pthread_exit抛出一个特殊异常"。
后面跟着下面的代码
class ThreadExitException
{
public:
ThreadExitException (void* return_value)
: thread_return_value_ (return_value) { }
void* DoThreadExit ()
{
pthread_exit (thread_return_value_);
}
private:
void* thread_return_value_;
};
void do_some_work ()
{
while (1)
{
/* Do some useful things here...*/
if (should_exit_thread_immediately ())
throw ThreadExitException (/* thread’s return value = */ NULL);
}
}
void* thread_function (void*)
{
try
{
do_some_work ();
}
catch (ThreadExitException ex)
{
ex.DoThreadExit ();
}
return NULL;
}
据我所知…如果调用pthread_exit,则可能不会调用堆栈中所有自动变量的析构函数。因此,我们使用异常处理来确保对所有变量调用析构函数。(引用自解释:"通过抛出ThreadExitException而不是直接调用pthread_exit,异常在顶级线程函数中被捕获,线程堆栈上的所有局部变量将被正确销毁异常向上渗透。"
根据pthread_exit
的手册页
"任何由pthread_cleanup_push(3)建立的尚未被弹出的清理处理程序,将被弹出(与它们被推送的顺序相反)执行。如果线程有任何特定于线程的数据,那么在清理处理程序执行后,将调用相应的析构函数,在 .
表示函数调用析构函数,因此自动变量将被释放。那么为什么有必要使用代码所演示的异常处理呢?
线程特定的数据与您所理解的不同。线程特定的数据是已经设置的全局数据,以便每个线程获得全局数据的单独副本。所以线程特定的数据并不像你想象的那样存在于堆栈中。
不,它说析构函数是为线程特定的数据调用的。这与c++在线程调用栈中的自动变量上调用析构函数完全不同。
请参阅man pthread_key_create
,查看与线程特定数据相关的析构函数的文档。
int pthread_key_create(pthread_key_t *key, void (*destructor)(void*));
[…一个可选的析构函数可以与每个键值相关联。在线程退出时,如果键值具有非NULL的析构函数指针,并且线程具有与该键关联的非NULL值,则该键的值被设置为NULL,然后使用先前关联的值作为唯一参数调用所指向的函数。如果一个线程在退出时存在多个析构函数,则不指定析构函数调用的顺序。[…]
- 如何创建一个CMake变量,除非显式重写,否则使用默认值
- 将成员变量添加到共享库中的类中,不会破坏二进制兼容性吗
- 将数组的地址分配给变量并删除
- Pthread段错误,使用指向main中变量的指针
- 在 pthread 中使用共享变量
- 使用全局变量显示C++在使用 pthread 时比指针慢 100%?
- 成员变量的更新值不会在 PTHREAD 中的线程路由函数中重新排列
- C++ pthread,两个线程读取一个全局变量
- Pthread 条件变量即使设置为 PTHREAD_PROCESS_SHARED,也不会发出信号
- Pthread条件变量是连续轮询的替代品,是真的吗
- 在静态初始化期间,pthread线程变量何时开始存在
- pthread互斥锁定和解锁每个变量
- Pthread用于许多类变量
- Boost和Pthread条件变量之间的差异
- 从pthread访问外部类变量
- Pthread条件变量不可预测的结果
- 如何在没有__thread的情况下创建pthread特定的变量
- 线程同步pthread条件变量
- ' pthread '的运行函数如何修改外部变量
- 在运行时擦除持有pthread的变量