Здравствуйте, Кодт, Вы писали:
SC>>Если бы функция rand сохраняла свое состояние в глобальной переменной, то при вызове ее из разных потоков были бы та-а-акие фейерверки. Поэтому каждый поток имеет свой seed.
К>Ну прямо уж феерверки.
Если никак не защищать — то прямо фейерверки. Я сам наблюдал на самодельном генераторе.
К> Что, сложно сделать атомарный доступ к семечку? На interlocked?
Тоже вариант.
К>Конечно, TLS — это тоже решение: у каждого потока семечко своё.
Там ведь структура ptd не только для rand нужна, поэтому почему бы еще и seed туда не запихать, я такое решение вполне понимаю.
К>Но ведь требования о независимости случайных последовательностей в разных потоках в Стандарте не записаны, так что это самодеятельность MS.
Обратного там тоже не записано. Значит MS действует здесь в рамках стандарта.
К>Ладно бы поведение нереентерабельной функции было не определено при реентере. (Как, скажем, printf с двух рук стрелять).
К>Это легко исправляется, если мы поместим вызов такой функции в критическую секцию.
К>К>CCriticalSectrion csRand;
К>int tsrand() { CCritSecLock lock(&csRand); return rand(); }
К>
К>Однако, хотя вызовы строго сериализованы, эффект прежний — у нас не одна последовательность, а много, на каждый поток своя.
Если критическая секция без спинкаунта — это сильный удар по производительности. Если со спинкаунтом — то конечно значительно менее сильный, но что-то мне кажется что решение с tls проще и эффективнее.
--
Sergey Chadov
... << RSDN@Home 1.2.0 alpha rev. 685>>