C++ 程序结束时的 thread_local 向量分段错误

Posted

技术标签:

【中文标题】C++ 程序结束时的 thread_local 向量分段错误【英文标题】:thread_local vector segmentation fault at end of program in C++ 【发布时间】:2015-09-24 00:37:26 【问题描述】:

我正在尝试制作一个多线程程序,但在线程局部向量方面遇到了一个奇怪的问题。这是(精简到只有错误)代码:

#include <vector>
#include <iostream>
thread_local std::vector<int> vec;
int main()
    vec.push_back(3);
    std::cout << vec[0];
    // Make you push enter to show the error is at the end
    std::cin.ignore();

程序编译正常,运行正常,但按回车后,我收到“程序已停止工作”消息。我在 gdb 中运行它并收到此错误:

Program received signal SIGSEGV, Segmentation fault.
0x004030b0 in std::vector<int, std::allocator<int> >::~vector() ()

不知何故,向量的析构函数中有一个错误。用断点遍历它表明这个错误是在程序退出时发生的。

使向量不是线程本地的可以使程序工作,但我当然需要它是线程本地的。如果我根本不与向量交互,程序就可以正常工作。

我想我必须使用一些替代方法,但有人知道如何使这项工作有效吗?谢谢!

编辑:我很愚蠢,忘记了有关我的系统的更多信息。我正在使用 Windows Vista 64 位。运行 g++ -v 给了我:

Using built-in specs.
COLLECT_GCC=g++
COLLECT_LTO_WRAPPER=C:/MinGW/bin/../libexec/gcc/i686-w64-mingw32/5.2.0/lto-wrapper.exe
Target: i686-w64-mingw32
Configured with [edited out because it's too big and probably not relevant]
Thread model: posix
gcc version 5.2.0 (i686-posix-dwarf-rev0, Built by MinGW-W64 project)

线程模型实际上可能与它有很大关系。

【问题讨论】:

您的主题是如何创建的?你join线程吗? 本题给出的代码使用gcc 5.1.1编译执行成功,没有错误 代码适用于我在 Linux GCC 5.1.1 上。您使用的是什么编译器/版本? 您是否使用-pthread 标志进行编译? 问题取决于编译器/平台。似乎 thread_local 存储没有在适当的时间调用析构函数,这样当程序关闭时,析构函数就会失效。尝试使用 std::shared_ptr > vecptr 存储向量,然后在退出前显式重置 ptr...看看是否有任何改变。 【参考方案1】:

它取决于设置;我已经使用 64 位 MinGW 在 Windows 7(64 位)上成功编译并运行了您的示例程序。也许这与您在 64 位平台上使用 32 位 MinGW 安装有关?我的 g++ -v 给出了以下内容(与你的版本和线程模型相同,不同的拱门):

Using built-in specs.
COLLECT_GCC=g++
Target: x86_64-w64-mingw32
Thread model: posix
gcc version 5.2.0 (x86_64-posix-seh-rev0, Built by MinGW-W64 project)

【讨论】:

以上是关于C++ 程序结束时的 thread_local 向量分段错误的主要内容,如果未能解决你的问题,请参考以下文章

C++:如何使用thread_local来声明一个指针变量?

具有与 std::thread 不同的线程库的 C++ thread_local

走进C++11(四十五) thread_local

在 Qt 中的 C++ 中添加 C 函数时的构建问题

非托管 C++ 代码向托管代码发送字符串的错误

thread_local unordered_map 加上 AccessibleObjectFromWindow 不在 WinXP 中运行