В рамках задания один из моих профессоров дал мне код, который выглядит примерно так:
namespace
{
thread_local unsigned seed; // for use with rand_r
void run_custom_tests() {
// set this thread's seed
seed = 0;
// insert some random numbers into a map
std::map<int, int> m;
for (int i = 0; i < key_max; ++i)
m.insert(i, rand_r(&seed));
auto random_operations = [&]()
{
// do more stuff with rand_r(&seed)
};
std::thread t1(random_operations);
std::thread t2(random_operations);
t1.join();
t2.join();
}
} // end anonymous namespace
void test_driver()
{
run_custom_tests();
}
Мой вопрос заключается в том, какова цель этого thread_local
семена? Я понимаю, что вы не можете разрешить двум потокам обращаться к одной и той же глобальной переменной. Но почему бы просто не сделать это локальным? поскольку seed
используется только для заполнения этой карты и внутри лямбды, и каждый поток имеет свой собственный стек, разве локальная переменная не достигнет той же цели?
Я хорошо справился с заданием, так как суть не в том, чтобы понять это использование thread_local
, Но я все еще смущен этим аспектом программы.
Из документации Linux:
Как и rand (), rand_r () возвращает псевдослучайное целое число в диапазоне [0, RAND_MAX]. Аргумент seedp — это указатель на неподписанное int, которое используется для хранения состояния между вызовами.
Ранее в документации упоминалось, что rand
а также rand_r
не являются потокобезопасными.
Поэтому состояние должно быть либо разделено на поток, либо вызов должен быть защищен мьютексом.
Других решений пока нет …