SFML community forums
Help => System => Topic started by: Richy19 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:
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?
-
Use a boolean, change it when your thread function ends and test it in your main thread.
-
so
bool threadRunning = false;
void loadFiles()
{
threadRunning = true
...
threadRunning = false
}
sf::Thread loadingThread( &loadFiles);
loadingThread.Launch();
while( threadRunning)
{
Animate and draw loading screen
}
-
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:
//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;
}
-
Why do you have
loadingThread.Wait();
-
Why do you have
loadingThread.Wait();
Here: http://www.sfml-dev.org/tutorials/1.6/system-threads.php
On the section: Terminating a thread
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.
-
The destructor calls Wait(), so there's no need to explicitely call it unless you want to wait before the thread instance is destroyed.
-
Passing it to the function as a reference didnt work, but using a global variable did
-
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.
-
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.
-
I tried this:
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
-
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.