EDIT: tl; dr - эта проблема, по-видимому, ограничена небольшим набором комбинаций OS/компилятор/библиотека и теперь отслеживается в GCC Bugzilla как Ошибка 68921 благодаря @JonathanWakely.
Я жду в будущем, и я заметил, что top
показывает 100% использование ЦП и strace
показывает постоянный поток вызовов futex
:
...
[pid 15141] futex(0x9d19a24, FUTEX_WAIT, -2147483648, {4222429828, 3077922816}) = -1 EINVAL (Invalid argument)
...
Это на Linux 4.2.0 (32-разрядный i686
), скомпилированный с версией gcc версии 5.2.1.
Вот моя минимально жизнеспособная примерная программа:
#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;
}
и вот вызов компилятора (такое же поведение без -g
):
g++ --std=c++11 -Wall -g -o spin-wait spin-wait.cc -pthread
Есть ли более эффективная альтернатива?
Вот логически-подобная программа, использующая std::condition_variable
, которая выглядит намного лучше:
#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;
}
Я делаю что-то не так с моим кодом std::future
, или это реализация в моем libstdc++
просто так плохо?