这是我第一次尝试使用std::future
。这段代码为什么会产生竞态条件?
我有三个不同的文件,我想同时解析。有三个功能可以做到这一点,称为parseSentences
,parseTags
和parseLinks
。通过使用一个非常简单的lambda函数[]() { parser->function(); }
,其中parser
是一个静态变量,函数是我之前命名的三个函数之一,它们中的每一个都使用std::async
单独的线程启动。
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
的指针为空,导致分段错误。
如果有人有线索,我会很感激。
没有看这个bug,这个设计看起来仍然很可怕。 'thisParserInstance'存在什么?它的名字是不正确的:它是第一个进入该函数的实例,* forever *。为什么不直接使用'this'? – GManNickG
为什么这么复杂?只需将'[this]'放入捕获列表中... –
@GManNickG我应该解释这一点。该功能在程序执行过程中只调用一次。我需要将解析器实例传递给3个新线程,并且我看不到任何更干净的方法。 – qdii