这是我第一次尝试使用std::future
。
我有三个不同的文件要同时解析。三个功能就是这样做的。称为parseSentences
,parseTags
和parseLinks
。通过使用一个非常简单的lambda函数std::async
,使用[]() { parser->function(); }
在每个单独的线程中启动它们,其中parser
是一个静态变量,函数是我命名的三个函数之一先前。
int parser::start()
{
int ret = SUCCESS;
ASSERT( m_output != nullptr );
static parser * thisParserInstance = this;
// parsing files
std::future<int> parseSentence = std::async(std::launch::async, []() { return thisParserInstance->parseSentences(); } );
std::future<int> parseLinksResult = std::async(std::launch::async, []() { return thisParserInstance->parseLinks(); } );
std::future<int> parseTagsResult = std::async(std::launch::async, []() { return thisParserInstance->parseTags(); } );
// retrieving the results
ret = parseSentence.get();
const int linksResult = parseLinksResult.get();
const int tagsResult = parseTagsResult.get();
if (ret == SUCCESS)
ret = linksResult == SUCCESS ? tagsResult : linksResult;
return ret;
}
现在,当我在gdb中运行程序时,在销毁std::future
局部变量之一时会发生分段错误。这一刻有2个线程在运行。
线程#1的调用堆栈是here。
线程#2的调用堆栈是here。
请注意,第一个调用堆栈中指向this
的指针为空,从而导致分段错误。
如果有人有线索,我会很感激。
答案 0 :(得分:3)
这里有一个大问题:
static parser * thisParserInstance = this;
首次调用该函数时初始化,然后在未来的调用中保持不变。因此,如果您在一个对象上调用该函数,销毁该对象,然后在第二个对象上调用它,您实际上正在处理一个指向已解除对象的悬空指针。这肯定会给出不明确的行为。
没有理由使用静态变量; lambdas可以捕获this
并对正确的对象采取行动。或者更简单地,如评论中所建议的,使用async
的可变形式将this
绑定到成员函数:
std::async(std::launch::async, &parser::parseSentences, this);
答案 1 :(得分:1)
对不起伙计们。
这是解决方案:std::future exception on gcc experimental implementation of C++0x
与-lpthread
关联后,错误消失了。谢谢你的其他评论,但他们非常乐于助人。