2017-11-11 104 views
0

我想在调用所有C++ thread_local析构函数之后做一些工作。 这是平台特定的 - Android,所以我有权访问pthreadsC++ thread_local析构函数与pthread析构函数

问题是,当应该调用dd析构函数时,在C++ thread_local析构函数之前或之后?或者他们可以交错?

我测试了在C++之后调用的Linux Mint和pthread析构函数。

+0

我怀疑你会发现thread_local是通过pthread_key_create实现的。 –

+0

@RichardHodges我也期待这样,起初......但! pthread_key_create销毁顺序未定义,C++ thread_local析构函数需要按顺序排列。他们不能只是纯粹的线程。所以,他们可能不能被交错...因此 - 他们都被调用或之前,或之后...... – tower120

+0

其实,在godbolt上玩耍似乎gcc实际上使用寄存器来跟踪thread_specific数据。 –

回答

1

bionic/pthread_exit.cpp当前具有相同的顺序:

void pthread_exit(void* return_value) { 
    // Call dtors for thread_local objects first. 
    __cxa_thread_finalize(); 
    // Call the TLS destructors. 
    pthread_key_clean_all(); 

然而,该未记录的行为你不应该建立依赖它的东西。

+0

如果我将从pthread析构函数重新注册pthread析构函数,如下所示:https://stackoverflow.com/a/47237684/1559666?文档说析构函数的调用顺序是未定义的,但它表示它将进行迭代... C++ thread_local析构函数不能重新注册自身(标准行为),所以如果我们跳过一次,在第二次迭代时我们保证应该执行在C++之后。对? – tower120

+1

@ tower120不,不保证,如果C++ thread_local不使用pthread析构函数。 – ephemient

+0

嗯...确实... – tower120

0

libstdc++来自海湾合作委员会使用pthread_key_create万一平台不提供__cxa_thread_atexit_impl。在这种情况下,C++析构函数在POSIX析构函数的中间运行。

据我所知,没有标准要求任何特定的行为,因为C++不知道POSIX,而POSIX不知道C++,所以两种标准都没有说明这里会发生什么。在线程销毁期间还有一些涉及线程本地数据复活的情况,这些数据在实现中会有所不同。 (一个典型的例子是用于从线程局部变量的析构函数来登录每线程记录器对象。)