Reputation: 1
i have problem with my code. This function pushes a product into queue.
void producent(bool &cont,std::queue<std::string> &queue,std::mutex &mtx, int &milliseconds)
{
while (cont)
{
mtx.lock();
if (queue.size() >= MAX_QUEUE_SIZE)
{
mtx.unlock();
std::cerr << "buffor full " << std::endl;
}
else
{
std::string product = generate();
std::cerr << "producent: " << product << " " << std::endl;
queue.push(product);
mtx.unlock();
}
std::this_thread::sleep_for(std::chrono::milliseconds(milliseconds));
}
}
this function generates a string of 10 signs, which are pushed by void producent function().
std::string generate() {
std::string temp;
temp.resize(10);
for (int i = 0; i < 10; i++) {
temp[i] = rand() % ('z' - 'a' + 1) + 'a';
}
return temp;
}
My question is: why, when i create 2 threads like this:
std::thread prod(producent, std::ref(wykonuj),std::ref(kolejka), std::ref(kolejka_mtx),std::ref(t));
std::thread prod1(producent, std::ref(wykonuj), std::ref(kolejka), std::ref(kolejka_mtx), std::ref(t));
both of them give me same result, for example the outcome is:
producent: qweasdzxca
producent: qweasdzxca
i wanted those outcomes to be different, thats why i used mutex, but it didnt work. Can someone give me some advices?
Upvotes: 0
Views: 99
Reputation: 66194
Assuming your implementation has a thread-safe rand()
(probably unwise), both threads are using the same initial random seed (the default of 1, in this case), and thus producing the same sequence. Rather than doing that, embrace the the C++ <random>
offerings, and as far as that goes, the uniform distribution offerings as well.
#include <algorithm>
#include <random>
#include <string>
std::string generate(int n=10)
{
std::mt19937 prng{ std::random_device{}() };
std::uniform_int_distribution<int> dist('a', 'z');
std::string result;
std::generate_n(std::back_inserter(result), n, [&]() { return dist(prng); });
return result;
}
Executed 10x on 10x threads, this produced:
ysudtdcaeq
hwpeyiyyav
dlsdshltyo
pkfafhooxr
nmoxerbqpy
ydauzdvoaj
brjqjgxrgg
ezdsmbhygb
fpdgbkxfut
elywaokbyv
That, or something similar, should produce what you seek.
Note: the above will not work as-expected on platforms where a
..z
is non-contiguous. If you're on such a beast (typically OS/400 or OS/390 EBCDIC), an alternate solution is required.
Upvotes: 1
Reputation: 104524
rand
doesn't share a seed between threads. Each thread has its own seed - but without explicitly setting it differently in both threads via srand()
, it's going to be the same.
Hence, generate
invoked by both threads will produce the same string.
The docs suggest rand_r
is the thread safe version, but both functions are threads safe in modern implementations.
Upvotes: 1