你能帮我理解为什么这段代码会给我一个段错误吗?我创建线程的方式会不会有问题?我很难理解这个问题。
#include <fstream>
#include <sstream>
#include <thread>
#include <iostream>
#include <algorithm>
#include <new>
#include <thread>
#include <string>
class temp {
private:
std::thread m_thread;
std::vector<std::string> m_tokens;
public:
temp()
{
m_thread = std::thread(&temp::run, this);
}
void run()
{
while (1) {
std::string token;
std::cin >> token;
if (std::ranges::find(m_tokens, token) == m_tokens.end()) {
std::cout << "duplicate token" << token << "\n";
continue;
}
m_tokens.push_back(token);
std::cout << token << " added\n";
}
}
void join()
{
m_thread.join();
}
};
int main(int argc, char **argv)
{
temp t;
t.join();
return EXIT_SUCCESS;
}
ThreadSanitizer:DEADLYSIGNAL
==19246==ERROR: ThreadSanitizer: SEGV on unknown address 0x000000000000 (pc 0x7f81d5f98880 bp 0x7b0800000020 sp 0x7f81d30bf298 T19247)
==19246==The signal is caused by a WRITE memory access.
==19246==Hint: address points to the zero page.
#0 __tsan_func_entry <null> (libtsan.so.0+0x9e880)
#1 std::thread::_State_impl<std::thread::_Invoker<std::tuple<void (temp::*)(), temp*> > >::_M_run() /opt/rh/devtoolset-11/root/usr/include/c++/11/bits/std_thread.h:211 (trading+0x41e3a3)
#2 execute_native_thread_routine <null> (trading+0x437ab3)
#3 start_thread <null> (libpthread.so.0+0x7ea4)
#4 clone <null> (libc.so.6+0xfeb0c)
ThreadSanitizer can not provide additional info.
SUMMARY: ThreadSanitizer: SEGV (/lib64/libtsan.so.0+0x9e880) in __tsan_func_entry
==19246==ABORTING
怎么可能当我直接运行它时代码运行没有任何问题,但是当作为线程运行时却出现段错误?
您必须在主线程中的
.join()
对象上调用 std::thread
(例如在 temp
的析构函数中),以便让主线程等待 std::thread
管理的线程退出。
无限循环不能替代它,没有可观察到的副作用的无限循环在 C++ 中具有未定义的行为。编译器确实在它们永远不会被执行的假设下进行优化,有时甚至会为包含它们的函数(例如 Clang)编译完全无意义的东西,或者只是简单地删除它们。