SFML community forums

Help => System => Topic started by: Walta69 on May 03, 2014, 11:06:46 pm

Title: Threads not running in parallel
Post by: Walta69 on May 03, 2014, 11:06:46 pm
For some reason, when I make a new sf::Thread and launch it, it stops my main thread from continuing :/
Here is my code:

The Server constructor makes a new thread as shown below

#include "Server.h"
#include "Client.h"

#include <SFML/Graphics.hpp>

int main()
{
   sf::Text inputText; // text input by the user
   std::string input;
   bool hasChosen = false;
   sf::RenderWindow window(sf::VideoMode(800, 200), "Input", sf::Style::Titlebar);
   while (window.isOpen())
   {
      sf::Event e;
      while (window.pollEvent(e))
      {
         if (e.type == sf::Event::KeyPressed)
         {
            if (e.key.code == sf::Keyboard::Return)
            {

            }
            else if (e.key.code == sf::Keyboard::Escape)
            {
               window.close();
            }
            else if (e.key.code == sf::Keyboard::S)
            {
               if (!hasChosen)
               {
                  hasChosen = true;
                  Server server(8080); // start server
                  std::cout << "Test";
               }
            }
            else if (e.key.code == sf::Keyboard::C)
            {
               if (!hasChosen)
               {
                  hasChosen = true;
                  Client client(sf::IpAddress::getLocalAddress(), 8080);
               }
               
            }
         }
      }
      window.clear();
      window.draw(inputText);
      window.display();
   }

Note my Server Class constructor:

Server::Server(int port)
{
   listener.listen(port);
   selector.add(listener);
   done = false;
   sf::Thread serverThread(&Server::startServer, this);
   serverThread.launch();

   listener.close(); // close the server when we are done
}
Title: Re: Threads not running in parallel
Post by: Ixrec on May 03, 2014, 11:13:02 pm
Read the threads tutorial more carefully.  The sf::Thread gets destroyed at the end of the function where you create it, and its destructor waits for the actual thread to finish executing.
Title: Re: Threads not running in parallel
Post by: Walta69 on May 03, 2014, 11:14:10 pm
Alriight so what is the purpose of having multiple threads if theyre all waiting for the others to finish?
Title: Re: Threads not running in parallel
Post by: Ixrec on May 03, 2014, 11:17:23 pm
You're supposed to create the thread at a higher scope if you want it to live longer than the current function (just like every other resource class in SFML).  Again, read the tutorial.

In your case, you probably want to make the sf::Thread object a member of your Server class.


P.S. Since std::thread is a thing now, consider using that instead if you have access to C++11.
Title: Re: Threads not running in parallel
Post by: Walta69 on May 03, 2014, 11:25:08 pm
I tried that and it didn't work. The program never leaves the server constructor. The startServer() method
that the thread calls has an infinite while loop in it. My problem is that for some reason, while the thread is
running the while loop, it pauses everything else and I can't even move the window around which defeats
the whole purpose of multithreading.
Title: Re: Threads not running in parallel
Post by: Walta69 on May 03, 2014, 11:25:41 pm
std::thread yields the same results as sf::Thread in this case :(
Title: Re: Threads not running in parallel
Post by: Ixrec on May 03, 2014, 11:27:13 pm
Show us the new code that isn't working.  It's probably still an error in how you're using them.

By the way, std::thread is better than sf::Thread, but not in any way that will magically fix these errors.  The high-level behavior of the two classes is relatively similar.
Title: Re: Threads not running in parallel
Post by: Walta69 on May 03, 2014, 11:30:27 pm
Server::Server(int port)
{
   listener.listen(port);
   selector.add(listener);
   done = false;
   serverThread = new sf::Thread(&Server::startServer, this);
   serverThread->launch();

}

where serverThread is a member of Server of pointer type
Title: Re: Threads not running in parallel
Post by: Ixrec on May 03, 2014, 11:34:27 pm
I just noticed in your main() code above you also create the Server inside a block where it will get destroyed almost immediately.  The Server's destructor will then destroy all of its members.

Move the Server object outside of the main loop, unless you really want to create and destroy a new one every frame.  You'll probably have to move your constructor logic into an init() function.
Title: Re: Threads not running in parallel
Post by: Walta69 on May 03, 2014, 11:39:07 pm
It still makes no difference. Im pretty sure that my members aren't being deleted because my thread is running all the time. I put a std::cout in the thread and it is running permanently yet the "window thread" is just pausing.
Title: Re: Threads not running in parallel
Post by: Ixrec on May 03, 2014, 11:44:21 pm
The whole problem here is that the thread's destructor waits for it to finish.  Your main thread is pausing *because* the Server and its Thread are being destroyed.  The thread tutorial is pretty clear about this.

If your code still has this issue after you fix those scope problems, then show us what it looks like now so we can confirm you actually fixed it, and then maybe we can figure out what the new cause is.
Title: Re: Threads not running in parallel
Post by: Walta69 on May 03, 2014, 11:48:04 pm
Ok wait, I did a test method here to show that the thread is not being destroyed:

Server::Server(int port)
{
   listener.listen(port);
   selector.add(listener);
   done = false;
   serverThread = new std::thread(&Server::test, this);
   serverThread->join();
}
void Server::test()
{
   while (true)
   {
      std::cout << "This is a test \n";
   }
}

The program continuously outputs "this is a test"
Title: Re: Threads not running in parallel
Post by: Walta69 on May 03, 2014, 11:48:24 pm
Note I am now using std::thread
Title: Re: Threads not running in parallel
Post by: Ixrec on May 03, 2014, 11:52:52 pm
In C++ the word "destroy" has a very specific meaning, which includes the object's destructor getting called and a few other bits of cleanup.  It does NOT mean your computer magically forgets the object ever existed and goes back to whatever it was doing before.

sf::Thread's destructor waits for the thread to finish, if it hasn't already.  If that thread never finishes, then of course whatever thread called its destructor will be stuck waiting on it forever.

By the way, std::thread's destructor terminates the program if the thread hasn't finished.
Title: Re: Threads not running in parallel
Post by: Walta69 on May 03, 2014, 11:54:24 pm
So what do you suggest I do?
Title: Re: Threads not running in parallel
Post by: Ixrec on May 03, 2014, 11:56:49 pm
Put your objects in the correct scope so they live as long as you want them to.  This is an important principle for C++ code in general, not just for using resource objects like threads.  You need to understand when objects' constructors and destructors get called, and what they do.

Your Server object should be created in main(), before the main loop begins.

The Server's sf::Thread should be a member variable that gets initialized in the constructor and launched in a method, NOT a local variable that gets created, initialized, launched and destroyed all in the constrcutor.
Title: Re: Threads not running in parallel
Post by: Walta69 on May 04, 2014, 12:01:48 am
I have done all of the above:

void Server::StartThread()
{
   serverThread = new std::thread(&Server::test, this);
   serverThread->join();
}

which gets called in the main as follows:

int main()
{
   Server * server;
   server = new Server(8080); // start server
...
...
...
            else if (e.key.code == sf::Keyboard::S)
            {
               if (!hasChosen)
               {
                  hasChosen = true;
                  std::cout << "Test";
                  server->StartThread();
               }
            }
...
...
...
Title: Re: Threads not running in parallel
Post by: Ixrec on May 04, 2014, 12:07:39 am
join() waits for the thread to finish.  I don't think you want to call that in StartThread().
Title: Re: Threads not running in parallel
Post by: Walta69 on May 04, 2014, 12:11:49 am
I am a retard.
Title: Re: Threads not running in parallel
Post by: Walta69 on May 04, 2014, 12:12:17 am
Thank you :O
Title: Re: Threads not running in parallel
Post by: Ixrec on May 04, 2014, 12:14:18 am
Phew, glad you finally got it to work.