【发布时间】:2012-08-27 22:12:02
【问题描述】:
这是我第一次尝试使用std::future。
我要同时解析三个不同的文件。三个功能分别做到这一点。称为parseSentences、parseTags 和parseLinks。它们中的每一个都使用std::async 通过一个非常简单的 lambda 函数在单独的线程中启动:[]() { 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的指针为空,导致分段错误。
如果有人有线索,我将不胜感激。
【问题讨论】:
-
不看bug,这个设计还是有点吓人。
thisParserInstance存在什么?它的名字不正确:它是第一个进入函数实例的 this,forever。为什么不直接使用this? -
为什么这么复杂?只需将
[this]放入捕获列表... -
@GManNickG 我应该解释一下。该函数只在程序执行期间被调用一次。我需要将解析器实例传递给 3 个新线程,但我看不到任何更简洁的方法。
-
你应该发布一个有这个问题的完整程序,这样我们就不必猜测你在其他地方做了什么。
-
由于解析器实例被传递给所有三个线程,它立即提出了该实例正在做什么的问题。如果您怀疑数据竞争,解析器实例是最明显的罪魁祸首。
标签: c++ multithreading c++11 race-condition