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

Author Topic: Using threads to load stuff  (Read 5652 times)

0 Members and 1 Guest are viewing this topic.

Richy19

  • Full Member
  • ***
  • Posts: 190
    • View Profile
Using threads to load stuff
« on: September 07, 2011, 08:49:42 pm »
I want to use a thread to load all the assets and while this is happening animate a loading screen.

The way I thoughht I would do it is:

Code: [Select]

void loadFiles()
{
    ...
}

sf::Thread loadingThread( &loadFiles);
loadingThread.Launch();

while(loadingThread.isRunning)
{
    Animate and draw loading screen
}


The problem is that there is no way to find out if the thread is still running, it there any way to do this?

Laurent

  • Administrator
  • Hero Member
  • *****
  • Posts: 32498
    • View Profile
    • SFML's website
    • Email
Using threads to load stuff
« Reply #1 on: September 07, 2011, 08:57:37 pm »
Use a boolean, change it when your thread function ends and test it in your main thread.
Laurent Gomila - SFML developer

Richy19

  • Full Member
  • ***
  • Posts: 190
    • View Profile
Using threads to load stuff
« Reply #2 on: September 07, 2011, 09:18:10 pm »
so

Code: [Select]
bool threadRunning = false;

void loadFiles()
{
 threadRunning = true
    ...
 threadRunning = false
}

sf::Thread loadingThread( &loadFiles);
loadingThread.Launch();

while( threadRunning)
{
    Animate and draw loading screen
}

coolhome

  • Jr. Member
  • **
  • Posts: 59
    • View Profile
Using threads to load stuff
« Reply #3 on: September 08, 2011, 08:29:09 am »
Yeah that would work. Instead of using global bool you could reference the bool and pass it to the function. I just think it would probably be cleaner code. Here is an example of what i was talking about. Make sure you make things thread-safe! :D

Example:
Code: [Select]

//SFML 2.0
void LoadingThreadFunc(bool &isRunning)
{
isRunning = true;

for(int i = 1; i != 51; ++i)
{
std::cout << "[LoadingThread] " << i << "/50 has been loaded." << std::endl;
sf::Sleep(1);
}

isRunning = false;
}
int main()
{
bool isThreadRunning = false;
sf::Thread loadingThread(&LoadingThreadFunc, isThreadRunning);
loadingThread.Launch();

while(isThreadRunning)
{
//Run the state of displaying progress and what not.
}

loadingThread.Wait();
system("PAUSE");

return false;
}
CoderZilla - Everything Programming

Richy19

  • Full Member
  • ***
  • Posts: 190
    • View Profile
Using threads to load stuff
« Reply #4 on: September 08, 2011, 10:56:13 am »
Why do you have

loadingThread.Wait();

Contadotempo

  • Full Member
  • ***
  • Posts: 167
  • Firelink Shrine
    • View Profile
Using threads to load stuff
« Reply #5 on: September 08, 2011, 04:25:03 pm »
Quote from: "Richy19"
Why do you have

loadingThread.Wait();

Here: http://www.sfml-dev.org/tutorials/1.6/system-threads.php
On the section: Terminating a thread

Quote
The only way to safely terminate a running thread is simply to wait for it to finish by itself. To wait for a thread, you can use its Wait() function


Though the tutorial is for SFML 1.6, some parts might still apply to 2.0.

Laurent

  • Administrator
  • Hero Member
  • *****
  • Posts: 32498
    • View Profile
    • SFML's website
    • Email
Using threads to load stuff
« Reply #6 on: September 08, 2011, 04:35:59 pm »
The destructor calls Wait(), so there's no need to explicitely call it unless you want to wait before the thread instance is destroyed.
Laurent Gomila - SFML developer

Richy19

  • Full Member
  • ***
  • Posts: 190
    • View Profile
Using threads to load stuff
« Reply #7 on: September 08, 2011, 04:52:05 pm »
Passing it to the function as a reference didnt work, but using a global variable did

Laurent

  • Administrator
  • Hero Member
  • *****
  • Posts: 32498
    • View Profile
    • SFML's website
    • Email
Using threads to load stuff
« Reply #8 on: September 08, 2011, 05:32:12 pm »
You should use a pointer instead. References can't be forwarded properly by sf::Thread to the threaded function, you'd have to use a wrapper like boost::ref.
Laurent Gomila - SFML developer

MorleyDev

  • Full Member
  • ***
  • Posts: 219
  • "It is not enough for code to work."
    • View Profile
    • http://www.morleydev.co.uk/
Using threads to load stuff
« Reply #9 on: September 08, 2011, 05:42:36 pm »
Also it's probably best to declare that bool as volatile. Otherwise when you compile the Release build using the highest levels of optimisation the compiler may optimise it out and you enter an endless loop, since in a single threaded environment that would be a completely apt optimisation.

Even languages that seem pretty well geared for multithreading don't seem to have compilers thread-aware enough to avoid those kinds of optimisations without prompts from the programmer.

And don't set the bool to true in the actual loop, either do it before the thread starts or wait for it to become true before you start looking for it to become false. There's no guarantee the OS thread scheduler won't screw you over and have enough of a nanosecond delay that the while won't be checked before the bool is assigned.  It's the kind of bug that could happen 1 in 100 runs and is why multithreading, even the simple stuff, is considered so difficult: It's so easy to do something that seems like it would work, and does in 95% of cases, but will fail at seemingly random times.
UnitTest11 - A unit testing library in C++ written to take advantage of C++11.

All code is guilty until proven innocent, unworthy until tested, and pointless without singular and well-defined purpose.

Richy19

  • Full Member
  • ***
  • Posts: 190
    • View Profile
Using threads to load stuff
« Reply #10 on: September 08, 2011, 08:59:15 pm »
I tried this:

Code: [Select]
void LoadingThreadFunc(volatile bool *isThreadRunning)
{
    // isThreadRunning = true;

    for(int i = 1; i != 51; ++i)
    {
        std::cout << "[LoadingThread] " << i << "/50 has been loaded." << std::endl;
        sf::Sleep(10);
    }

    *isThreadRunning = false;
}

int main()
{

    volatile bool *isThreadRunning;// = true;
    *isThreadRunning = true;

    sf::Thread loadingThread(&LoadingThreadFunc, isThreadRunning);
    loadingThread.Launch();

    std::cout << isThreadRunning << std::endl;

    while(*isThreadRunning)
    {
        std::cout << "Loading" << std::endl;
    }
    return 0;
}


but it just crashes

Laurent

  • Administrator
  • Hero Member
  • *****
  • Posts: 32498
    • View Profile
    • SFML's website
    • Email
Using threads to load stuff
« Reply #11 on: September 08, 2011, 10:38:08 pm »
You're declaring and using a pointer to a bool that is not initialized. You should rather declare a plain bool and pass its address.
Laurent Gomila - SFML developer