這是我第一次嘗試使用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