Welcome, Guest. Please login or register. Did you miss your activation email?

Author Topic: multithreading and srand  (Read 11478 times)

0 Members and 1 Guest are viewing this topic.

vechestva

  • Newbie
  • *
  • Posts: 25
    • View Profile
multithreading and srand
« on: December 07, 2012, 01:58:46 pm »
Hi.  :)
How to use a randomizer with multithreading?
simple ex:
class Myc
{
public:
        Myc()
        {
        }

        ~Myc()
        {
                for (int i = 0; i < threads.size(); ++i)
                        if(sf::Thread* thr = threads[i])
                        {
                                thr->terminate();
                                delete thr;
                        }
                threads.clear();
        }

        void Start()
        {
                // 3 thread
                for (int i = 0; i < 3; ++i)
                        threads.push_back(new sf::Thread(&Myc::ThrFun, this));

                for (int i = 0; i < threads.size(); ++i)
                        threads[i]->launch();
        }

        void ThrFun()
        {
                sf::Clock clock;

                while (true)
                {
                        if (clock.getElapsedTime().asSeconds() >= 3)
                        {
                                // problem
                                int r = rand()%100+1;
                                std::cout << r << std::endl;

                                clock.restart();
                        }
                }
        }

private:
        std::vector<sf::Thread*> threads;
};

int main()
{
        srand((unsigned)time(NULL));

        Myc m;
        m.Start();

        std::cin.get();
}
 

result:
The same value in each thread. Since the mutex does not work, or I did not use true.
I do not know much English.

gyscos

  • Jr. Member
  • **
  • Posts: 69
    • View Profile
Re: multithreading and srand
« Reply #1 on: December 07, 2012, 02:15:12 pm »
rand() is not thread-safe.
http://linux.die.net/man/3/rand

Also, this doesn't really concern SFML, and is just a general C question.

Just google "rand thread safe" and you'll find plenty of information :)

binary1248

  • SFML Team
  • Hero Member
  • *****
  • Posts: 1405
  • I am awesome.
    • View Profile
    • The server that really shouldn't be running
Re: multithreading and srand
« Reply #2 on: December 07, 2012, 04:44:17 pm »
Or you can use something more modern like my favourite:

#include <ctime>
#include <iostream>
#include <random>

int main () {
        std::mt19937 generator( static_cast<unsigned int>( time( NULL ) ) );
        std::uniform_int_distribution<int> distribution( 1, 100 );

        std::cout << "Random value: " << distribution( generator ) << std::endl;

        return 0;
}
 

You would have to create one generator and one distribution per thread but I think that is acceptable if you want to keep things simple. If you are getting the same values from all threads you might need to seed with something else than time( NULL ) because it returns the same time if you call it multiple times within the same second. If you have support for the new <chrono> library then you should use that instead.
SFGUI # SFNUL # GLS # Wyrm <- Why do I waste my time on such a useless project? Because I am awesome (first meaning).

vechestva

  • Newbie
  • *
  • Posts: 25
    • View Profile
Re: multithreading and srand
« Reply #3 on: December 08, 2012, 04:32:04 am »
I have visual studio 2008. There is no support <random> and rand_r (drand48_r). How to solve the problem? (change "IDE" is not an option).
I do not know much English.

FRex

  • Hero Member
  • *****
  • Posts: 1845
  • Back to C++ gamedev with SFML in May 2023
    • View Profile
    • Email
Re: multithreading and srand
« Reply #4 on: December 08, 2012, 04:45:33 am »
The closest equivalent - Boost.Random? It's headers only + 'binary component for random_device'.
Back to C++ gamedev with SFML in May 2023

vechestva

  • Newbie
  • *
  • Posts: 25
    • View Profile
Re: multithreading and srand
« Reply #5 on: December 08, 2012, 05:22:36 am »
I do not know much English.

cire

  • Full Member
  • ***
  • Posts: 138
    • View Profile
Re: multithreading and srand
« Reply #6 on: December 08, 2012, 06:33:06 am »

vechestva

  • Newbie
  • *
  • Posts: 25
    • View Profile
Re: multithreading and srand
« Reply #7 on: December 08, 2012, 10:26:12 am »
I do not know much English.

Nexus

  • SFML Team
  • Hero Member
  • *****
  • Posts: 6286
  • Thor Developer
    • View Profile
    • Bromeon
Re: multithreading and srand
« Reply #8 on: December 08, 2012, 10:42:27 am »
In order to use TR1 on Visual Studio 2008, you have to install the Service Pack 1. Why don't you want to use Boost? It contains tons of useful features, not only random generation.

The alternative is to protect global rand() calls with a mutex. But this can quickly become slow. An own random engine per thread is much cleaner. And you can enforce deterministic generation of random numbers, which may be helpful for debugging.
« Last Edit: December 08, 2012, 10:44:12 am by Nexus »
Zloxx II: action platformer
Thor Library: particle systems, animations, dot products, ...
SFML Game Development:

cire

  • Full Member
  • ***
  • Posts: 138
    • View Profile
Re: multithreading and srand
« Reply #9 on: December 08, 2012, 10:54:00 am »
Quote
I have visual studio 2008. There is no support <random> and rand_r (drand48_r).

All that says to me is that you didn't actually take the time to read the material in the link.

vechestva

  • Newbie
  • *
  • Posts: 25
    • View Profile
Re: multithreading and srand
« Reply #10 on: December 08, 2012, 01:50:46 pm »
thx, but:
tons
This is the key word. ;)

The alternative is to protect global rand() calls with a mutex. But this can quickly become slow. An own random engine per thread is much cleaner. And you can enforce deterministic generation of random numbers, which may be helpful for debugging.
Mutex also fails. :'(
Since the mutex does not work, or I did not use true.
I do not know much English.

Laurent

  • Administrator
  • Hero Member
  • *****
  • Posts: 32504
    • View Profile
    • SFML's website
    • Email
Re: multithreading and srand
« Reply #11 on: December 08, 2012, 01:55:42 pm »
You didn't show us how you tried to use the mutex, and didn't say how it failed.
Laurent Gomila - SFML developer

Nexus

  • SFML Team
  • Hero Member
  • *****
  • Posts: 6286
  • Thor Developer
    • View Profile
    • Bromeon
Re: multithreading and srand
« Reply #12 on: December 08, 2012, 02:40:21 pm »
tons
This is the key word. ;)
You know that Boost is a collection of libraries, written by different authors? Designs differ sometimes strongly between them. Boost.Random isn't the kind of library which is massively overengineered, it is even part of the C++ standard library now.

Take a more detailed look at Boost and don't just believe what you've heard, I am sure there are parts which you find useful :)
Zloxx II: action platformer
Thor Library: particle systems, animations, dot products, ...
SFML Game Development:

vechestva

  • Newbie
  • *
  • Posts: 25
    • View Profile
Re: multithreading and srand
« Reply #13 on: December 09, 2012, 02:13:20 pm »
You didn't show us how you tried to use the mutex, and didn't say how it failed.
class Myc
{
public:
        Myc()
        {
        }

        ~Myc()
        {
                for (int i = 0; i < m_threads.size(); ++i)
                        if(sf::Thread* thr = m_threads[i])
                        {
                                thr->terminate();
                                delete thr;
                        }
                m_threads.clear();
        }

        void Start()
        {
                // 3 thread
                for (int i = 0; i < 3; ++i)
                        m_threads.push_back(new sf::Thread(&Myc::ThrFun, this));

                for (int i = 0; i < m_threads.size(); ++i)
                        m_threads[i]->launch();
        }

        void ThrFun()
        {
                sf::Clock clock;

                while (true)
                {
                        if (clock.getElapsedTime().asSeconds() >= 3)
                        {
                                // problem
                                m_mutex.lock();
                                int r = rand()%100+1;
                                m_mutex.unlock();
                                std::cout << r << std::endl;

                                clock.restart();
                        }
                }
        }

private:
        std::vector<sf::Thread*> m_threads;
        sf::Mutex m_mutex;
};

int main()
{
        srand((unsigned)time(NULL));

        Myc m;
        m.Start();

        std::cin.get();
}
I do not know much English.

Laurent

  • Administrator
  • Hero Member
  • *****
  • Posts: 32504
    • View Profile
    • SFML's website
    • Email
Re: multithreading and srand
« Reply #14 on: December 09, 2012, 02:30:37 pm »
And what's the problem with this code?
Laurent Gomila - SFML developer