Reputation: 12963
This is my first attempt at using std::future
.
I have three different files that I want to parse at the same time. Three functions do that, resp. called parseSentences
, parseTags
and parseLinks
. Each of them is launched in a separate thread using std::async
by using a very simple lambda function: []() { parser->function(); }
, where parser
is a static variable and function is one of the three functions I have named previously.
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;
}
Now when I run my program in gdb, a segmentation fault occurs at the destruction of one of the std::future
local variable. There are 2 threads running at that moment.
Thread #1’s call stack is here.
Thread #2’s call stack is here.
Note that the pointer to this
in the first call stack is null, resulting in the segmentation fault.
If anyone has a clue, I would be thankful.
Upvotes: 3
Views: 806
Reputation: 254461
One big problem is here:
static parser * thisParserInstance = this;
That's initialised the first time you call the function, and then left unchanged on future calls. So if you call the function on one object, destroy that object, and then call it on a second object, you'll actually be working on a dangling pointer to the defunct object. That will certainly give undefined behaviour.
There's no reason to use a static variable; the lambdas can capture this
and act on the correct object. Or more simply, as suggested in the comments, use the variadic form of async
to bind this
to the member function:
std::async(std::launch::async, &parser::parseSentences, this);
Upvotes: 3
Reputation: 12963
Sorry guys.
here is the solution: std::future exception on gcc experimental implementation of C++0x
After linking with -lpthread
, the error disappeared. Thanks for your other remarks, though, they were very helpful.
Upvotes: 1