У меня проблема с генерацией случайного числа в C в Windows. Вкратце, я хочу сгенерировать 7 чисел, равных 0 или 1. Затем функция суммирует эти числа, результатом будет индекс глобального определенного массива, и значение этого индекса увеличится на 1. Но в функция генератора, я всегда получаю одну и ту же последовательность чисел. Что я делаю неправильно?
#include <windows.h>
#include <stdio.h>
#include <time.h>
int cells[8];
int generator(int n) {
int i;
int sum = 0;
for (i = 0; i < n; i++) {
int random_number = rand() % 2 + 0;
printf("%d ",random_number);
sum += random_number;
}
printf("\n%d\n",sum);
return sum;
}
DWORD WINAPI ThreadFunc(void *data) {
cells[generator(7)] =+ 1;
return 0;
}
int main() {
srand(time(NULL));
for (int i = 0; i < 10; ++i) {
HANDLE thread = CreateThread(NULL, 0, ThreadFunc, NULL, 0, NULL);
WaitForSingleObject(thread, INFINITE);
}
for (int j = 0; j < 8; ++j) {
printf("%i: %i\n", j, cells[j]);
}
}
См. Что означает =+ в C?
Ребята, я исправил эту ошибку, но это не моя проблема. Моя проблема заключается в том, что каждый вызов функции печатает одни и те же значения. Например; первая итерация в цикле: 1 1 0 0 1 1 1. Вторая итерация: 1 1 0 0 1 1 1 и так далее. Он всегда дает одинаковые значения.





Вам не нужно потокобезопасное случайное число. Ваш код всегда вызывает rand в точной детерминированной последовательности, потому что вы ждете завершения каждого потока, прежде чем запускать следующий. Ваша проблема в следующем;
cells[generator(7)] =+ 1;
Это устанавливает ячейку в +1, а не добавляет к ней единицу.
Я пробовал это, но это не проблема. Я все еще получаю те же цифры.
Помимо проблемы с "=+ 1"... есть дополнительная проблема с кодом:
Microsoft прямо говорит, что начальное число зависит от потока (см. https://docs.microsoft.com/en-us/cpp/c-runtime-library/reference/srand):
The srand function sets the starting point for generating a series of pseudorandom integers in the current thread.
Это означает, что начальное значение (генератор последовательности /) сохраняется в локальном хранилище потока. Однако они не указывают, что произойдет, если вы вызовете srand перед созданием дополнительных потоков. Поэтому мне кажется вполне вероятным, что локальное хранилище потока, содержащее начальное значение, будет либо скопировано из инициализирующего потока, либо оно будет просто повторно инициализировано с начальным значением по умолчанию в каждом потоке при первом вызове rand, как если бы вы вызывали не былоsrand совсем.
В любом случае все потоки в любом случае будут генерировать одну и ту же псевдослучайную последовательность.
Следовательно, вам будет лучше вызвать time один раз, добавить индекс потока к этому начальному значению времени, передать результат в качестве аргумента функции потока, а затем использовать это (специфичное для потока) значение в качестве аргумента для srandв пределах потока. По крайней мере, тогда каждый поток будет начинаться с другого начального начального значения.
Впечатляющая сложность! :-) Кроме того, в строке
cells[generator(7)] =+ 1;вы, вероятно, хотели использовать+=.