Увеличьте потоки/мьютексы, почему это работает?

код:

#include <iostream>
#include "stdafx.h"
#include <boost/thread.hpp>
#include <boost/thread/mutex.hpp>

using namespace std;
boost::mutex mut;
double results[10];

void doubler(int x) {
//boost::mutex::scoped_lock lck(mut);
 results[x] = x*2;
}

int _tmain(int argc, _TCHAR* argv[])
{
 boost::thread_group thds;
 for (int x = 10; x>0; x--) {
  boost::thread *Thread = new boost::thread(&doubler, x);
  thds.add_thread(Thread);
 }

 thds.join_all();

 for (int x = 0; x<10; x++) {
  cout << results[x] << endl;
 }

 return 0;
}

Вывод:

0
2
4
6
8
10
12
14
16
18
Press any key to continue . . .

Итак... мой вопрос в том, почему это работает (насколько я могу судить, я запускал его примерно 20 раз), производя вышеупомянутый вывод, даже если блокировка закомментирована? Я думал, что общая идея:

in each thread:
calculate 2*x
copy results to CPU register(s)
store calculation in correct part of array
copy results back to main(shared) memory

Я бы подумал, что при всех, кроме идеальных условиях, это приведет к тому, что часть массива результатов будет иметь 0 значений. Это только копирование требуемого двойника массива в регистр cpu? Или это просто слишком мало для расчета, чтобы получить вытеснение до того, как он вернет результат обратно в ram? Спасибо.

Ответ 1

Назначение имеет lvalue типа double слева и что lvalue является единственным объектом, к которому обращается поток. Поскольку каждый поток обращается к другому объекту, нет расы данных.

Обратите внимание, что подписи массива не являются доступом.

Ответ 2

Он работает из-за строки thds.join_all();. Основной поток выполнения прерывается здесь до тех пор, пока все остальные потоки не будут завершены, а затем продолжит печать массива. Поэтому вы знаете, что все значения массива были сохранены до их печати. Если вы закомментируете эту строку, вы получите непредсказуемые результаты.