简体   繁体   中英

main terminating a thread with infinite loop

I'm quite new with multi-threading. Below is an example code I was trying to run. Please forgive syntax errors (if any), as I'm going by memory.
The issue with the code below is that it terminates immediately, whereas it should be running forever. I wanted to know why the main is calling the deconstructor, even though there is a while (true) statement.

There are no other classes, so it is not due to interactions with others. The only thing the main does is to create an object of type myclass, and call function1() below.

    int main()
    {
        myclass Object;
        Object.function1();

        return 0;
    }

    /**** new file   ******/
    typedef boost::shared_ptr<boost::thread> thread_pointer;

    class myclass
    {
    public:
        // some stuff
        void function1();
    private:
        // some stuff
        void myfunction();
        thread_pointer tr_ptr;  
    };

    ~myclass() {
        tr_ptr->join();
    }

    void myclass::function1()
    {
        // some stuff   
        tr_ptr = thread_ptr(new boost::thread(&myclass::myfunction, this));  

    }

    void myclass::myfunction()
    {
        // some stuff
        while(true){
             // some stuff
        } 
    }

A 2nd thread will get created at the c.function1() call, but then the main thread keeps going. However, you do have thread_ptr->join() in the desctuctor which will cause an infinite loop (depending on system timing) if you declare and use myclass like in example 1 because the destructor is called as main exits.

The main thread will block on thread->join() until the child thread exits. So for example 1, when the main thread of execution leaves the scope where c is defined, the destructor will be invoked and the main thread will call join() where it will wait until the child thread exits and since the child never exits, the main thread will block forever.

Example 1:

int main(int argc,char *argv[])
{
   myclass c;

   c.function1();
}

However if you declare and use it like this:

Example 2:

int main(int argc,char *argv[])
{
   myclass *c = new myclass();

   c->function1();
}

Then since objects that are created via new must be explicitly destructed then the destructor will not be called and the program will exit immediately because join() is not called.

if you further change it to this:

Example 3:

int main(int argc,char *argv[])
{
   myclass *c = new myclass();

   c->function1();
   delete c;
}

You get an infinite loop again because again invoking the destructor will cause the main thread to call join()

Your main needs to be something like this:

int main()
{
    myclass Object;
    Object.function1();

    while(true){
    }
    // Or wait for a join by the thread...

    return 0;
}

You object's destructor is called because when main terminates, the Object becomes out of scope.

Life of Threads are tied to it's calling Process

When a process exits/terminates, so do all of it's threads. A quick way to ensure you process does not terminate is to add a while(true) loop after you create the thread.

As mentioned in your comment, you want to "encapsulate" the while loop in the class. You may add it in function1() like this:

void myclass::function1()
{
    // some stuff   
    tr_ptr = thread_ptr(new boost::thread(&myclass::myfunction, this));  

    while(true){
        // Do something
    } 

}

However, it will "block" your main thread, losing most advantages of implementing a thread in the first place.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM