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

Author Topic: Thread startet from a Thread  (Read 3212 times)

0 Members and 1 Guest are viewing this topic.

chriss

  • Newbie
  • *
  • Posts: 7
    • View Profile
Thread startet from a Thread
« on: July 22, 2009, 12:24:33 am »
Hi,

there is somethin i don't understand at the Thread class.
When i write my own class and let it inerhit sf::Thread, i can start it that way

Code: [Select]

myThreadClass myThread;
myThread.Launch();


This works really well, but when I do that within a running thread, the function Run of myThreadClass isn't called.

It seams that the Object is destroyed, before the Run Method could be launched.
In functions of the Main thread does everything work well.
Any idears, how this could be?

klusark

  • Newbie
  • *
  • Posts: 45
    • View Profile
Thread startet from a Thread
« Reply #1 on: July 22, 2009, 02:22:12 am »
Does the thread that starts the thread stop?
Witch object is being destroyed?

Laurent

  • Administrator
  • Hero Member
  • *****
  • Posts: 32451
    • View Profile
    • SFML's website
    • Email
Thread startet from a Thread
« Reply #2 on: July 22, 2009, 07:47:52 am »
Can you show more code? If possible, a minimal and complete example?
Laurent Gomila - SFML developer

chriss

  • Newbie
  • *
  • Posts: 7
    • View Profile
Thread startet from a Thread
« Reply #3 on: August 22, 2009, 12:01:29 am »
It is as i thought.
The primary Thread terminates and so the subthreads are terminated before they could start.


This code does not start the sub threads.

Code: [Select]

#include <iostream>
#include "SFML/System.hpp"

class TC2 : public sf::Thread{
public: int number;
private :
    virtual void Run()
    {
        // Print something...
        for (int i = 0; i < 10; ++i)
            std::cout << "I'm the thread number " << number << std::endl;
    }

};

class TC1 : public sf::Thread{
private :
    virtual void Run()
    {
std::cout << "I'm the main thread" << std::endl;
        // Print something...
        for (int i = 0; i < 10; ++i)
{
TC2 tc;
tc.number = i;
tc.Launch();
}
    }

};

int main(int argc, char** argv)
{
TC1 tc;
tc.Launch();

system("PAUSE");
}


This code starts the Threads (but produces memory leaks)

Code: [Select]

#include <iostream>
#include "SFML/System.hpp"

class TC2 : public sf::Thread{
public: int number;
private :
    virtual void Run()
    {
        // Print something...
        for (int i = 0; i < 10; ++i)
            std::cout << "I'm the thread number " << number << std::endl;
    }

};

class TC1 : public sf::Thread{
private :
    virtual void Run()
    {
std::cout << "I'm the main thread" << std::endl;
        // Print something...
        for (int i = 0; i < 10; ++i)
{
TC2 *tc = new TC2;
tc->number = i;
tc->Launch();
}
    }

};

int main(int argc, char** argv)
{
TC1 tc;
tc.Launch();

system("PAUSE");
}

Jaenis

  • Newbie
  • *
  • Posts: 48
    • View Profile
Thread startet from a Thread
« Reply #4 on: August 24, 2009, 05:35:30 pm »
This is quite simple actually.
Read this part from your first example:
Code: [Select]
{
TC2 tc;
tc.number = i;
tc.Launch();
} // What happens to variable tc at this point?

Answer is that class TC2 destructor will get called.
Since it is inherited from sf::Thread, also the thread will be closed.

When you allocate all threads will new in second example, their destructors will not get called at that point.
So if you have to do something like this, you need to allocate them dynamically and store pointers somewhere.

chriss

  • Newbie
  • *
  • Posts: 7
    • View Profile
Thread startet from a Thread
« Reply #5 on: August 24, 2009, 09:48:02 pm »
Yes i know, thanks.

In my current projecti'm storing those pointers.
First placed my objects on the stack. So i was wondering, why the threads didn't start.

Id didn't tried it, but would somithing like this work?
Code: [Select]

class TC2 : public sf::Thread{
public: int number;
private :
    virtual void Run()
    {
        // Print something...
        for (int i = 0; i < 10; ++i)
            std::cout << "I'm the thread number " << number << std::endl;
        delete this;
    }

};



Not a nice way, but could do the job, if this still deletes the thread from the system.

Jaenis

  • Newbie
  • *
  • Posts: 48
    • View Profile
Thread startet from a Thread
« Reply #6 on: August 25, 2009, 05:52:24 am »
"delete this" is okay if you never allocate that variable to stack.

Small example to illustrate this:
Code: [Select]
class Foo
{
void del(void)
{
delete this;
}
}

Not okay:
{
class Foo tmp;
tmp.del();        // Deletes the pointer
}                 // Variable tmp goes out of scope, destructor will be called again, undefined behavior

Okay:
{
class Foo *tmp= new Foo;
tmp.del();        // Deletes the pointer
}
But since this can lead into very interesting bugs, I would recommend you doing something else :)


So, you want to launch x number of threads and see that they will get freed when they are done?
Maybe just store them in a list? And wait them to finish
Code: [Select]

#include <list>

// List for allocated threads
std::list <sf::Thread *> CreatedThreads;


class TC1 : public sf::Thread{
private :
    virtual void Run()
    {
      std::cout << "I'm the main thread" << std::endl;
        // Print something...
        for (int i = 0; i < 10; ++i)
      {
         TC2 *tc = new TC2;
         CreatedThreads.push_back(tc); // Store the thread pointer
         tc->number = i;
         tc->Launch();
      }
    }

};


int main(int argc, char** argv)
{
TC1 tc;
tc.Launch();

system("PAUSE"); // Needed in this example for TC1 thread to run before next line

// Wait all threads to finish
while (!CreatedThreads.empty())
{
sf::Thread *Thread=CreatedThreads.front();
CreatedThreads.pop_front();

// Wait thread to finish and free memory when done
Thread->Wait();
delete Thread;
}

}