Description of the problem
std::async
seems to block even with std::launch::async
flag:
#include <iostream>
#include <future>
#include <chrono>
int main(void)
{
using namespace std::chrono_literals;
auto f = [](const char* s)
{
std::cout << s;
std::this_thread::sleep_for(2s);
std::cout << s;
};
std::cout << "start\n";
(void)std::async(std::launch::async, f, "1\n");
std::cout << "in between\n";
(void)std::async(std::launch::async, f, "2\n");
std::cout << "end\n";
return 0;
}
output shows that the execution is serialized. Even with std::launch::async
flag.
start
1
1
in between
2
2
end
But if I use returned std::future
, it suddenly starts to not block!
The only change I made is removing (void)
and adding auto r1 =
instead:
#include <iostream>
#include <future>
#include <chrono>
int main(void)
{
using namespace std::chrono_literals;
auto f = [](const char* s)
{
std::cout << s;
std::this_thread::sleep_for(2s);
std::cout << s;
};
std::cout << "start\n";
auto r1 = std::async(std::launch::async, f, "1\n");
std::cout << "in between\n";
auto r2 = std::async(std::launch::async, f, "2\n");
std::cout << "end\n";
return 0;
}
And, the result is quite different. It definitely shows that the execution is in parallel.
start
in between
1
end
2
1
2
I used gcc for CentOS devtoolset-7.
gcc (GCC) 7.2.1 20170829 (Red Hat 7.2.1-1)
Copyright (C) 2017 Free Software Foundation, Inc.
This is free software; see the source for copying conditions. There is NO
warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
My Makefile
is:
.PHONY: all clean
all: foo
SRCS := $(shell find . -name '*.cpp')
OBJS := $(SRCS:.cpp=.o)
foo: $(OBJS)
gcc -o $@ $^ -lstdc++ -pthread
%.o: %.cpp
gcc -std=c++17 -c -g -Wall -O0 -pthread -o $@ $<
clean:
rm -rf foo *.o
Question
Is this behaviour in the specification?
Or is it a gcc implementation bug?
Why does this happen?
Can someone explain this to me, please?