EDIT: tl;dr -- ce problème semble être limité à un petit ensemble de OS/compilateur/bibliothèque de combinaisons et est maintenant suivie dans le GCC Bugzilla comme Bug 68921 grâce à @JonathanWakely.
Je suis en attente sur un avenir, et j'ai remarqué qu' top
montre 100% d'utilisation du PROCESSEUR et de la strace
montre un flux régulier de futex
appels:
...
[pid 15141] futex(0x9d19a24, FUTEX_WAIT, -2147483648, {4222429828, 3077922816}) = -1 EINVAL (Invalid argument)
...
C'est sur Linux 4.2.0 (32 bits i686
), compilé avec gcc version 5.2.1.
Ici, c'est mon minimum viable exemple de programme:
#include <future>
#include <iostream>
#include <thread>
#include <unistd.h>
int main() {
std::promise<void> p;
auto f = p.get_future();
std::thread t([&p](){
std::cout << "Biding my time in a thread.\n";
sleep(10);
p.set_value();
});
std::cout << "Waiting.\n";
f.wait();
std::cout << "Done.\n";
t.join();
return 0;
}
et voici le compilateur invocation (même comportement sans -g
):
g++ --std=c++11 -Wall -g -o spin-wait spin-wait.cc -pthread
Est-il plus performant alternative?
Voici une logique similaire de programme à l'aide de std::condition_variable
qui semble fonctionner beaucoup mieux:
#include <condition_variable>
#include <iostream>
#include <mutex>
#include <thread>
#include <unistd.h>
int main() {
bool done = 0;
std::mutex m;
std::condition_variable cv;
std::thread t([&m, &cv, &done](){
std::cout << "Biding my time in a thread.\n";
sleep(10);
{
std::lock_guard<std::mutex> lock(m);
done = 1;
}
cv.notify_all();
});
std::cout << "Waiting.\n";
{
std::unique_lock<std::mutex> lock(m);
cv.wait(lock, [&done]{ return done; });
}
std::cout << "Done.\n";
t.join();
return 0;
}
Suis-je en train de faire quelque chose de mal avec mon std::future
-en fonction du code, ou est la mise en œuvre dans mon libstdc++
juste que mauvais?