gpt4 book ai didi

c++ - 为什么这段代码会产生竞争条件?

转载 作者:太空狗 更新时间:2023-10-29 21:04:08 28 4
gpt4 key购买 nike

这是我第一次尝试使用 std::future

我想同时解析三个不同的文件。三个功能分别做到了这一点。称为 parseSentencesparseTagsparseLinks。它们中的每一个都通过一个非常简单的 lambda 函数使用 std::async 在单独的线程中启动:[]() { parser->function(); },其中 parser 是一个静态变量,function 是我之前命名的三个函数之一。

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 的指针为空,从而导致段错误。

如果有人知道,我将不胜感激。

最佳答案

这里有一个大问题:

static parser * thisParserInstance = this;

这是在您第一次调用该函数时初始化的,然后在以后的调用中保持不变。因此,如果您在一个对象上调用该函数,销毁该对象,然后在第二个对象上调用它,您实际上是在处理一个指向已失效对象的悬空指针。这肯定会产生未定义的行为。

没有理由使用静态变量; lambda 可以捕获 this 并作用于正确的对象。或者更简单地说,如评论中所建议的那样,使用可变形式的 asyncthis 绑定(bind)到成员函数:

std::async(std::launch::async, &parser::parseSentences, this);

关于c++ - 为什么这段代码会产生竞争条件?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/12150342/

28 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com