anon
anon

Reputation: 210

Can you run a thread in another thread?

In my programm, I want to run two seperate thread, which are initalized and launched in the main thread. This concept works fine for me, but when I now have to make a cooldown on one of the child threads while it is not paused it seems to still pause the thread;

Think of this as an example:

#include <iostream>
#include <thread>

class testClass {
    static void grandchild();
    static void child();
public:
    void parent();
};

void testClass::grandchild() {
    //infinite loop of nothing;
    while (true);
}

void testClass::child() {
    //thread initalising and 
    std::thread grand(&testClass::grandchild);
    std::cout << "before join" << std::endl;
    grand.join();
    std::cout << "after join" << std::endl;
}

void testClass::parent() {
    std::thread child(&testClass::child);
    child.join();
}
int main() {
    testClass parentclass;
    parentclass.parent();
}

The output of this program now is

http://puu.sh/ppTkR/e29221e1b8.png

This also happens when I do this_thread::sleep_for and other functions which pause a thread. Can anyone explain me why this happens and what is possible for me to implement this properly or if this is even possible in C++?

Upvotes: 0

Views: 3771

Answers (3)

wally
wally

Reputation: 11002

Here is a modified program that uses the grandchild thread to wait for 3 seconds before changing a value.

The child thread keeps running.

#include <iostream>
#include <thread>
#include <atomic>
#include <chrono>

class testClass {
public:
    void grandchild();
    void child();
    void parent();
    std::atomic<int> value{0};
};

void testClass::grandchild()
{
    std::this_thread::sleep_for(std::chrono::seconds(3));
    value = 5;
}

void testClass::child()
{
    //thread initalising and 
    std::cout << "Starting grandchild thread.\n";
    std::thread grand(&testClass::grandchild,this);
    //grand.detach(); // could detach so that a join() will not be required later
    for (int x{0}; x<5; ++x) {
        std::cout << x << '\t' << value << '\n';
        std::this_thread::sleep_for(std::chrono::seconds(1));
    }
    grand.join();
}

void testClass::parent()
{
    std::cout << "Starting child thread.\n";
    std::thread child(&testClass::child, this);
    child.join();
}
int main()
{
    std::cout << "Starting program\n";
    std::cout << "Starting parent thread.\n";
    testClass parentclass;
    parentclass.parent();
}

output:

Starting program
Starting parent thread.
Starting child thread.
Starting grandchild thread.
0       0
1       0
2       0
3       5
4       5

live demo

Upvotes: 3

nugae
nugae

Reputation: 499

This program is behaving correctly.

  1. It displays "before join".

  2. It then waits until the infinite while(1) loop finishes.

  3. After an infinite time, it displays "after join".

If you intend different behaviour, perhaps you could explain what that different behaviour is.

Upvotes: 2

nwp
nwp

Reputation: 9991

.join() means "wait until that thread finishes". parent waits for child and child waits for grandchild and grandchild is stuck in an infinite loop, therefore nothing happens. You are effectively running single-threaded because you join with the threads you spawn.

You could not wait by using .detach() instead of .join(), but you should join all the threads before returning from main.

Upvotes: 3

Related Questions