이것은 내 첫 시도 인 std::future
입니다.이 코드가 경쟁 조건을 만드는 이유는 무엇입니까?
나는 동시에 세 가지 다른 파일을 분석하고 싶습니다. 세 가지 기능이 있습니다. parseSentences
, parseTags
및 parseLinks
이라고합니다. 이들 각각은 매우 간단한 람다 함수 인 []() { parser->function(); }
을 사용하여 std::async
을 사용하는 별도의 스레드에서 실행됩니다. 여기서 parser
은 정적 변수이고 function은 이전에 이름을 지정한 세 가지 함수 중 하나입니다. 내가 GDB 내 프로그램을 실행할 때
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;
}
지금, 세그먼트 오류는 std::future
지역 변수 중 하나의 파괴에서 발생한다. 그 순간에 2 개의 스레드가 실행 중입니다. 스레드 # 1의 호출 스택은 here입니다. 스레드 # 2의 호출 스택은 here입니다.
첫 번째 호출 스택의 this
에 대한 포인터가 null이므로 세그먼트 화 오류가 발생합니다.
아무도 단서가 있다면, 나는 감사 할 것이다.
버그를 보지 않고도이 디자인은 여전히 무서운 것처럼 보입니다. 'thisParserInstance'는 무엇입니까? 이름이 정확하지 않습니다. 함수의 인스턴스 인 * forever *를 처음 입력하는 것입니다. 'this'를 직접 사용하지 않겠습니까? – GManNickG
왜 그렇게 복잡합니까? 캡쳐리스트에'[this]'를 넣으십시오 ... –
@GManNickG 그걸 설명해야합니다. 이 함수는 프로그램 실행 중에 한 번만 호출됩니다. 파서 인스턴스를 3 개의 새 스레드에 전달해야했기 때문에 더 깨끗한 방법으로 작업을 수행 할 수 없었습니다. – qdii