Я новичок в многопоточном программировании, и я нашел std::atomic
в C++ 11.Как я могу правильно увеличить C++ 11 std :: atomic?
Итак, я попытался выяснить, сколько времени выполняются атомными операциями.
Я попробовал этот код:
using namespace std;
using namespace std::chrono;
constexpr int NUM_THREADS = 8;
constexpr int LIMIT = 100000;
atomic<int> sum = 0;
void foo(int idx) {
while (true) {
if (sum.load() >= LIMIT) {
return;
}
sum.fetch_add(1);
}
}
с main
:
int main(void) {
thread threads[NUM_THREADS];
auto start = high_resolution_clock::now();
for (int i = 0; i < NUM_THREADS; i++) {
threads[i] = thread(&foo, i);
}
for (int i = 0; i < NUM_THREADS; i++) {
threads[i].join();
}
auto du = high_resolution_clock::now() - start;
cout << "computing time\t\t" << duration_cast<milliseconds>(du).count() << "ms" << endl;
cout << "number of thread\t" << NUM_THREADS << endl;
cout << "sum\t\t\t" << sum << endl;
return 0;
}
Но sum
не всегда совпадает с LIMIT
.
Насколько я знаю, атомные операции поточно-безопасны при «вызове». Итак, да, я думаю, что мой код ошибочен, но я не мог понять, как сделать эту работу должным образом.
Как я могу получить правильный результат с этим main
?
(ну, эта версия будет делать sum
и LIMIT
равны, но я думаю, что это не лучший способ ...)
void foo(int idx) {
for (int i = 0; i < LIMIT/NUM_THREADS; i++) {
sum.fetch_add(1);
}
}
Первый из них не работает, потому что ваш чек и ваш инкремент являются двумя отдельными операциями, поэтому 2 потока могут читать что-то ниже LIMIT, и оба решают увеличить. – Borgleader
Ваша проблема заключается не в том, как увеличить атом - ваша проблема заключается в том, как атомизировать последовательность операций * two *. – Hurkyl
Вам необходимо либо http://en.cppreference.com/w/cpp/atomic/atomic/compare_exchange, либо mutex. –